// ----------------------------------
// RSDK Project: Sonic 1/Sonic 2
// Script Description: Player Object Object
// Script Author: Christian Whitehead/Simon Thomley
// Unpacked by Rubberduckycooly's script unpacker
// ----------------------------------

//-------Aliases-------//
private alias 1 		: TYPE_PLAYEROBJECT
public alias  256 		: GROUP_PLAYERS
public alias  65536 	: HITBOX_AUTO
public alias  arrayPos6 : currentPlayer
public alias  arrayPos7 : playerCount
private alias object[8].value14 : TimeOverFlag
private alias 20 : amy.spin.speed

public alias saveRAM[257] : saved.spindash
public alias saveRAM[258] : saved.speedCap
public alias saveRAM[259] : saved.airSpeedCap
public alias saveRAM[260] : saved.spikeBehavior
public alias saveRAM[261] : saved.shieldType
public alias saveRAM[262] : saved.superStates
public alias saveRAM[263] : saved.Jumplock
public alias saveRAM[264] : saved.Supermusic
public alias saveRAM[265] : saved.Dropdash
public alias saveRAM[266] : saved.Instashield
public alias saveRAM[267] : saved.Peelout
public alias saveRAM[268] : saved.FlightCancel
public alias saveRAM[269] : saved.SonicMaxDash
public alias saveRAM[270] : saved.Speen
public alias saveRAM[271] : saved.Supercancel
public alias saveRAM[272] : saved.Drowning
public alias saveRAM[273] : saved.Timer
public alias saveRAM[274] : saved.region
public alias saveRAM[275] : saved.UFO
public alias saveRAM[276] : saved.rotate
public alias saveRAM[277] : saved.invincibilityType
public alias saveRAM[280] : saved.gogoplus
public alias saveRAM[281] : saved.lives
public alias saveRAM[282] : saved.bubble
public alias saveRAM[283] : saved.specialSpin
public alias saveRAM[284] : saved.timeLimit
public alias saveRAM[285] : saved.GHZwater
public alias saveRAM[286] : saved.language
public alias saveRAM[287] : saved.elemental
public alias saveRAM[295]: saved.mobile
public alias saveRAM[297] : saved.TailsMaxDash
public alias saveRAM[298] : saved.KnuxMaxDash
public alias saveRAM[299] : saved.AmyMaxDash
public alias saveRAM[300] : saved.SuperMaxDash
public alias saveRAM[301] : saved.AmyMoveset

public alias saveRAM[302] : saved.ShadowJump
public alias saveRAM[303] : saved.ShadowClear
public alias saveRAM[304] : saved.ShadowPeelout
public alias saveRAM[305] : saved.ShadowCrouch
public alias saveRAM[307] : saved.ShadowFX
public alias saveRAM[309] : saved.ShadowInv
public alias saveRAM[310] : saved.ShadowClearSS

private alias object.value0 : player.rings
private alias object.value1 : player.timer
private alias object.value3 : player.drownCounter // Countdown before player moves to next drown "level"
private alias object.value4 : player.drownLevel
private alias object.value5 : player.CustomRollAnimSpeed
private alias object.value6 : player.speedShoes
private alias object.value7 : player.invincible
private alias object.value8 : player.invulnerable
private alias object.value9 : player.minRollSpeed
private alias object.value10 : player.animationReserve // Used by springs to store what animation will play after the bounce animation
private alias object.value11 : camera.lockTimer // A timer of how long the camera will stay locked for
private alias object.value12 : player.tailsFrame
private alias object.value13 : player.tailsAnim
private alias object.value14 : player.skidding
private alias object.value15 : player.dropDashCharge
private alias object.value16 : player.isPlayer2 // 0/false is player 1, 1/true if player 2
private alias object.value17 : debugMode.currentSelection
private alias object.value18 : player.sortedDrawOrder
private alias object.value19 : player.enemyChainCounter // How many enemies the player has bounced on in a row
private alias object.value20 : player.speedCap // Not to be confused with options.speedCap
private alias object.value21 : player.acceleration
private alias object.value22 : player.deceleration
private alias object.value23 : player.airAcceleration
private alias object.value24 : player.groundRotation
private alias object.value25 : player.gravityValue // Also used in underwater checks , 0x1000 if underwater, otherwise 0x3800. Not to be confused with player.gravity
private alias object.value26 : player.flightVelocity // Used by Tails only
private alias object.value27 : player.jumpVelocity
private alias object.value28 : player.jumpStrength
private alias object.value29 : player.rollingDecelerationA // Active rolling deceleration - With the player holding the opposite direction
private alias object.value30 : player.jumpOffset // Added to the player's position when jumping/rolling. Normally -5 for S&K, and -1 for Tails
private alias object.value31 : player.rollingDecelerationP // Passive rolling deceleration - Without the player holding the opposite direction
private alias object.value32 : player.jumpAbility // Used to store whatever function this player has for its jump ability
private alias object.value33 : player.spindashFunction // Used to store whatever function this player has for its spindash ability
private alias object.value34 : player.collisionEnabled
private alias object.value35 : player.doubleJumpState

private alias object.value36 : player.tailsGrabTimeout // Tails assist lockout timer
private alias object.value36 : player.gunReload // Tails assist dont exist

private alias object.value37 : player.shield // Current shield the player has, see above constants for what is what
private alias object.value38 : player.hitboxTop
private alias object.value39 : player.hitboxBottom
private alias object.value40 : player.hitboxLeft
private alias object.value41 : player.hitboxRight
private alias object.value42 : player.prevGravity
private alias object.value43 : player.jumpInTimer

private alias object.value44 : player.p2InputFunction
private alias object.value44 : player.gunTimer //Since P2 isn't in use for Shadow, we're gonna add this.

private alias object.value45 : player.autoJumpTimer
private alias object.value46 : player.targetLeaderPos.x
private alias object.value47 : player.targetLeaderPos.y


// Function declarations
reserve function PlayerObject_ProcessPlayer
reserve function PlayerObject_Blank
reserve function PlayerObject_HandleMovement
reserve function PlayerObject_HandleAirAcceleration
reserve function PlayerObject_HandleAirMovement
reserve function PlayerObject_ResetOnFloor
reserve function PlayerObject_StartJump
reserve function PlayerObject_StartSpindash
reserve function PlayerObject_StartTailsFlight
reserve function PlayerObject_StartKnuxGlide
reserve function PlayerObject_HandleGround
reserve function PlayerObject_HandleAir
reserve function PlayerObject_AirCtrlLock
reserve function PlayerObject_HandleRoll
reserve function PlayerObject_RollingJump
reserve function PlayerObject_LookingUp
reserve function PlayerObject_Crouching
reserve function PlayerObject_HandleSpindash
reserve function PlayerObject_HandleTailsFlight
reserve function PlayerObject_KnuxGlideLeft
reserve function PlayerObject_KnuxGlideRight
reserve function PlayerObject_KnuxGlideDrop
reserve function PlayerObject_KnuxGlideSlide
reserve function PlayerObject_KnuxWallClimb
reserve function PlayerObject_KnuxLedgePullUp
reserve function PlayerObject_Hurt
reserve function PlayerObject_Knockback
reserve function PlayerObject_Death
reserve function PlayerObject_Drown
reserve function PlayerObject_CheckTile
reserve function PlayerObject_Unknown1
reserve function PlayerObject_RollUnknown
reserve function PlayerObject_Unknown2
reserve function PlayerObject_Clinging
reserve function PlayerObject_WaterSlide
reserve function PlayerObject_FlyCarry
reserve function PlayerObject_HandleRunSpd2
reserve function PlayerObject_InitReplay
reserve function PlayerObject_RestorePowerup
reserve function PlayerObject_HandleSuperPalSonic
reserve function PlayerObject_HandleSuperPalTails
reserve function PlayerObject_HandleSuperPalKnux
reserve function PlayerObject_SwapPhysics
reserve function PlayerObject_ProcessSuperForms
reserve function PlayerObject_CheckHit
reserve function PlayerObject_BadnikBreak
reserve function PlayerObject_Hit
reserve function PlayerObject_FireHit
reserve function PlayerObject_LightningHit
reserve function PlayerObject_ProjectileHit
reserve function PlayerObject_SpikeHit
reserve function PlayerObject_Kill
reserve function PlayerObject_HandleRollAnimSpd
reserve function PlayerObject_HandleWalkAnimSpd
reserve function PlayerObject_HandleRunAnimSpd
reserve function PlayerObject_HandleRolling
reserve function PlayerObject_Transforming
reserve function PlayerObject_SuperTransform
reserve function PlayerObject_BubbleBounce
reserve function PlayerObject_HandleShieldAbilities
reserve function PlayerObject_StartFlyCarry
reserve function PlayerObject_DropDash
reserve function PlayerObject_HandleSuperPeel
reserve function PlayerObject_StartSuperPeel
reserve function PlayerObject_StartSpindashCD
reserve function PlayerObject_HandleSpindashCD
reserve function PlayerObject_HandleSuperPalAmy
reserve function PlayerObject_StartHammerSwing
reserve function PlayerObject_HandleHammerSwing
reserve function PlayerObject_StartHammerSpin
reserve function PlayerObject_HandleHammerSpin
reserve function PlayerObject_StartHop
reserve function PlayerObject_OuttaHere
reserve function PlayerObject_Force45
reserve function PlayerObject_MoveAnimate
reserve function PlayerObject_StartSecondJump
reserve function PlayerObject_ManiaRotate
reserve function PlayerObject_TopGlide
reserve function PlayerObject_EndSuper

reserve function PlayerObject_HandleShadowAbilities
reserve function PlayerObject_HandleGunShoot
reserve function PlayerObject_HandleAttack
reserve function PlayerObject_ChaosBlast

// doublejumpstate for Amy
//0 = Not jumped
//1 = Jumped
//2 = DOne both abilities
//3 = Done Hammer Jump
//4 = done hop


// Static Values
public value PlayerObject_LeaderX = 0;
public value PlayerObject_LeaderY = 0;
public value PlayerObject_SidekickX = 0;
public value PlayerObject_SidekickY = 0;
public value PlayerObject_SuperState = 0;
public value PlayerObject_value1 = 0;
public value PlayerObject_value2 = 0;
public value PlayerObject_value3 = 0;
public value PlayerObject_value4 = 0;
public value PlayerObject_value5 = 0;
public value PlayerObject_ReplayTable = 0;
public value PlayerObject_ReplayTablePos = 0;
public value PlayerObject_ReplaySize = 0;
public value PlayerObject_ReplayFrameCnt = 0;
public value PlayerObject_ReplayLength = 0;
public value PlayerObject_value13 = 0;
public value PlayerObject_value14 = 0;
public value PlayerObject_value15 = 0;
public value PlayerObject_value16 = 0;
public value PlayerObject_value17 = 0;
public value PlayerObject_value18 = 0;
public value PlayerObject_value19 = 0;
public value achievement.trigger = 0;

public value bullet.cap = 0;
public value AniSpeedStorage = 0;
public value object.GunBefore = 0;
public value BlastCharge = 0;


// Tables
public table PlayerObject_SonicSuperPal
	0x202080, 0x4040A0, 0x6060C0, 0x8080E0
	0x404060, 0x6060A0, 0x8080E0, 0xA0A0E0
	0x606040, 0x8080A0, 0xA0A0E0, 0xC0C0E0
	0x808040, 0xA0A0A0, 0xC0C0E0, 0xE0E0E0
	0xA0A040, 0xC0C0A0, 0xE0E0E0, 0xE0E0E0
	0xC0C040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0
	0xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0
	0xE0E060, 0xE0E0E0, 0xE0E0E0, 0xE0E0E0
	0xE0E080, 0xE0E0E0, 0xE0E0E0, 0xE0E0E0
	0xE0E060, 0xE0E0C0, 0xE0E0E0, 0xE0E0E0
	0xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0
	0xE0E020, 0xE0E080, 0xE0E0C0, 0xE0E0E0
	0xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E0
	0xE0E000, 0xE0E040, 0xE0E080, 0xE0E0C0
	0xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E0
	0xE0E000, 0xE0E080, 0xE0E0C0, 0xE0E0E0
end table

public table PlayerObject_SonicSuperAltPal
	0x202080, 0x4040A0, 0x6060C0, 0x8080E0 
	0x404060, 0x6060A0, 0x8080E0, 0xA0A0E0 
	0x606040, 0x8080A0, 0xA0A0E0, 0xC0C0E0 
	0x808040, 0xA0A0A0, 0xC0C0E0, 0xE0E0E0
	0xA0A040, 0xC0C0A0, 0xE0E0E0, 0xE0E0E0 
	0xC0C040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0 
	0xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0 
	0xE0E060, 0xE0E0E0, 0xE0E0E0, 0xE0E0E0
	0xE0E080, 0xE0E0E0, 0xE0E0E0, 0xE0E0E0 
	0xE0E060, 0xE0E0C0, 0xE0E0E0, 0xE0E0E0 
	0xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0 
	0xE0E020, 0xE0E080, 0xE0E0C0, 0xE0E0E0
	0xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E0 
	0xE0E000, 0xE0E040, 0xE0E080, 0xE0E0C0 
	0xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E0 
	0xE0E000, 0xE0E080, 0xE0E0C0, 0xE0E0E0
end table

public table PlayerObject_TailsSuperPal
	0x800000, 0xE08000, 0xE0A000, 0xA06040 
	0x800000, 0xE0A020, 0xE0C040, 0xA06040 
	0xA06040, 0xE0C040, 0xE0C080, 0xC06040 
	0xC06040, 0xE0C080, 0xE0E0A0, 0xE08040
	0xA06040, 0xE0C040, 0xE0C080, 0xC06040
	0x800000, 0xE0A020, 0xE0C040, 0xA06040
end table

public table PlayerObject_TailsSuperAltPal
	0x800000, 0xE08000, 0xE0A000, 0xA06040
	0x800000, 0xE0A020, 0xE0C040, 0xA06040
	0xA06040, 0xE0C040, 0xE0C080, 0xC06040
	0xC06040, 0xE0C080, 0xE0E0A0, 0xE08040
	0xA06040, 0xE0C040, 0xE0C080, 0xC06040
	0x800000, 0xE0A020, 0xE0C040, 0xA06040
end table

public table PlayerObject_KnuxSuperPal
	0x600020, 0xC00020, 0xE04060
	0x802040, 0xE04060, 0xE060A0
	0xA04060, 0xE06080, 0xE080C0
	0xC06080, 0xE080A0, 0xE0A0E0
	0xE080A0, 0xE0A0C0, 0xE0C0E0
	0xE0A0C0, 0xE0C0E0, 0xE0E0E0
	0xE080A0, 0xE0A0C0, 0xE0C0E0
	0xC06080, 0xE080A0, 0xE0A0E0
	0xA04060, 0xE06080, 0xE080C0
	0x802040, 0xE04060, 0xE060A0
end table

public table PlayerObject_KnuxSuperAltPal
	0x600020, 0xC00040, 0xE04080
	0x802040, 0xE04060, 0xE060A0
	0xA04060, 0xE06080, 0xE080C0
	0xC06080, 0xE080A0, 0xE0A0E0
	0xE080A0, 0xE0A0C0, 0xE0C0E0
	0xE0A0C0, 0xE0C0E0, 0xE0E0E0
	0xE080A0, 0xE0A0C0, 0xE0C0E0
	0xC06080, 0xE080A0, 0xE0A0E0
	0xA04060, 0xE06080, 0xE080C0
	0x802040, 0xE04060, 0xE060A0
end table

public table PlayerObject_AmySuperPal
	0xE080E0, 0xE060C0, 0xC040A0, 0x802060	
	0xE0A0E0, 0xE080E0, 0xE060C0, 0xA04080
	0xE0C0E0, 0xE0A0E0, 0xE080E0, 0xC060A0
	0xE0E0E0, 0xE0C0E0, 0xE0A0E0, 0xE080C0
	0xE0E0E0, 0xE0E0E0, 0xE0C0E0, 0xE0A0E0
	0xE0E0E0, 0xE0C0E0, 0xE0A0E0, 0xE080C0
	0xE0C0E0, 0xE0A0E0, 0xE080E0, 0xC060A0
	0xE0A0E0, 0xE080E0, 0xE060C0, 0xA04080
end table

public table PlayerObject_AmySuperAltPal
	0xE080E0, 0xE060C0, 0xC040A0, 0x802060	
	0xE0A0E0, 0xE080E0, 0xE060C0, 0xA04080
	0xE0C0E0, 0xE0A0E0, 0xE080E0, 0xC060A0
	0xE0E0E0, 0xE0C0E0, 0xE0A0E0, 0xE080C0
	0xE0E0E0, 0xE0E0E0, 0xE0C0E0, 0xE0A0E0
	0xE0E0E0, 0xE0C0E0, 0xE0A0E0, 0xE080C0
	0xE0C0E0, 0xE0A0E0, 0xE080E0, 0xC060A0
	0xE0A0E0, 0xE080E0, 0xE060C0, 0xA04080
end table

public table PlayerObject_ShadowSuperPal
	0x151515, 0x202420, 0x4b4545, 0x736a6a
	0x202420, 0x4b4545, 0x736a6a, 0x848484
	0x4b4545, 0x736a6a, 0x848484, 0xA5A5A5
	0x736a6a, 0x848484, 0xA5A5A5, 0xC6C6C6
	0xA0A040, 0xC0C0A0, 0xE0E0E0, 0xE0E0E0
	0xC0C040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0
	0xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0
	0xE0E060, 0xE0E0E0, 0xE0E0E0, 0xE0E0E0
	0xE0E080, 0xE0E0E0, 0xE0E0E0, 0xE0E0E0
	0xE0E060, 0xE0E0C0, 0xE0E0E0, 0xE0E0E0
	0xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0
	0xE0E020, 0xE0E080, 0xE0E0C0, 0xE0E0E0
	0xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E0
	0xE0E000, 0xE0E040, 0xE0E080, 0xE0E0C0
	0xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E0
	0xE0E000, 0xE0E080, 0xE0E0C0, 0xE0E0E0
end table

public table PlayerObject_ShadowSuperAltPal
	0x151515, 0x202420, 0x4b4545, 0x736a6a
	0x202420, 0x4b4545, 0x736a6a, 0x848484
	0x4b4545, 0x736a6a, 0x848484, 0xA5A5A5
	0x736a6a, 0x848484, 0xA5A5A5, 0xC6C6C6
	0xA0A040, 0xC0C0A0, 0xE0E0E0, 0xE0E0E0 
	0xC0C040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0 
	0xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0 
	0xE0E060, 0xE0E0E0, 0xE0E0E0, 0xE0E0E0
	0xE0E080, 0xE0E0E0, 0xE0E0E0, 0xE0E0E0 
	0xE0E060, 0xE0E0C0, 0xE0E0E0, 0xE0E0E0 
	0xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E0 
	0xE0E020, 0xE0E080, 0xE0E0C0, 0xE0E0E0
	0xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E0 
	0xE0E000, 0xE0E040, 0xE0E080, 0xE0E0C0 
	0xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E0 
	0xE0E000, 0xE0E080, 0xE0E0C0, 0xE0E0E0
end table

public table PlayerObject_SonicPhysicsTable
	0x60000, 0xC00,  0x1800, 0x600,  0x8000,  0x600, 0x68000, -0x40000
	0x30000, 0x600,  0xC00,  0x300,  0x4000,  0x300, 0x38000, -0x20000
	0xA0000, 0x3000, 0x6000, 0x1800, 0x10000, 0x600, 0x80000, -0x40000
	0x50000, 0x1800, 0x3000, 0xC00,  0x8000,  0x300, 0x38000, -0x20000
	0xC0000, 0x1800, 0x3000, 0xC00,  0x8000,  0x600, 0x68000, -0x40000
	0x60000, 0xC00,  0x1800, 0x600,  0x4000,  0x300, 0x38000, -0x20000
	0xC0000, 0x1800, 0x3000, 0xC00,  0x8000,  0x600, 0x80000, -0x40000
	0x60000, 0xC00,  0x1800, 0x600,  0x4000,  0x300, 0x38000, -0x20000
end table

public table PlayerObject_TailsPhysicsTable
	0x60000, 0xC00,  0x1800, 0x600,  0x8000,  0x600, 0x68000, -0x40000 
	0x30000, 0x600,  0xC00,  0x300,  0x4000,  0x300, 0x38000, -0x20000 
	0xA0000, 0x3000, 0x6000, 0x1800, 0x10000, 0x600, 0x80000, -0x40000 
	0x50000, 0x1800, 0x3000, 0xC00,  0x8000,  0x300, 0x38000, -0x20000 
	0xC0000, 0x1800, 0x3000, 0xC00,  0x8000,  0x600, 0x68000, -0x40000 
	0x60000, 0xC00,  0x1800, 0x600,  0x4000,  0x300, 0x38000, -0x20000 
	0xC0000, 0x1800, 0x3000, 0xC00,  0x8000,  0x600, 0x80000, -0x40000 
	0x60000, 0xC00,  0x1800, 0x600,  0x4000,  0x300, 0x38000, -0x20000
end table

public table PlayerObject_KnuxPhysicsTable
	0x60000, 0xC00,  0x1800, 0x600,  0x8000,  0x600, 0x60000, -0x40000
	0x30000, 0x600,  0xC00,  0x300,  0x4000,  0x300, 0x30000, -0x20000
	0xA0000, 0x3000, 0x6000, 0x1800, 0x10000, 0x600, 0x60000, -0x40000
	0x50000, 0x1800, 0x3000, 0xC00,  0x8000,  0x300, 0x30000, -0x20000
	0xC0000, 0x1800, 0x3000, 0xC00,  0x8000,  0x600, 0x60000, -0x40000
	0x60000, 0xC00,  0x1800, 0x600,  0x4000,  0x300, 0x30000, -0x20000
	0xC0000, 0x1800, 0x3000, 0xC00,  0x8000,  0x600, 0x60000, -0x40000
	0x60000, 0xC00,  0x1800, 0x600,  0x8000,  0x300, 0x30000, -0x20000
end table

public table PlayerObject_AmyPhysicsTable
	0x60000, 0xC00,  0x1800, 0x600,  0x8000,  0x600, 0x60000, -0x40000
	0x30000, 0x600,  0xC00,  0x300,  0x4000,  0x300, 0x30000, -0x20000
	0xA0000, 0x3000, 0x6000, 0x1800, 0x10000, 0x600, 0x60000, -0x40000
	0x50000, 0x1800, 0x3000, 0xC00,  0x8000,  0x300, 0x30000, -0x20000
	0xC0000, 0x1800, 0x3000, 0xC00,  0x8000,  0x600, 0x60000, -0x40000
	0x60000, 0xC00,  0x1800, 0x600,  0x4000,  0x300, 0x30000, -0x20000
	0xC0000, 0x1800, 0x3000, 0xC00,  0x8000,  0x600, 0x60000, -0x40000
	0x60000, 0xC00,  0x1800, 0x600,  0x8000,  0x300, 0x30000, -0x20000
end table

public table PlayerObject_ShadowPhysicsTable
	0x60000, 0xC00,  0x1800, 0x600,  0x8000,  0x600, 0x68000, -0x40000
	0x30000, 0x600,  0xC00,  0x300,  0x4000,  0x300, 0x38000, -0x20000
	0xA0000, 0x3000, 0x6000, 0x1800, 0x10000, 0x600, 0x80000, -0x40000
	0x50000, 0x1800, 0x3000, 0xC00,  0x8000,  0x300, 0x38000, -0x20000
	0xC0000, 0x1800, 0x3000, 0xC00,  0x8000,  0x600, 0x68000, -0x40000
	0x60000, 0xC00,  0x1800, 0x600,  0x4000,  0x300, 0x38000, -0x20000
	0xC0000, 0x1800, 0x3000, 0xC00,  0x8000,  0x600, 0x80000, -0x40000
	0x60000, 0xC00,  0x1800, 0x600,  0x4000,  0x300, 0x38000, -0x20000
end table

function PlayerObject_InitReplay
	PlayerObject_ReplayTablePos = 2
	PlayerObject_ReplayFrameCnt = 1
	currentPlayer = 0
	while currentPlayer < playerCount
		GetTableValue(object[currentPlayer].xpos, 0, PlayerObject_ReplayTable)
		GetTableValue(object[currentPlayer].ypos, 1, PlayerObject_ReplayTable)
		object[currentPlayer].controlMode = -1
		object[currentPlayer].up = 0
		object[currentPlayer].down = 0
		object[currentPlayer].left = 0
		object[currentPlayer].right = 0
		object[currentPlayer].jumpPress = 0
		object[currentPlayer].jumpHold = 0
		object[currentPlayer].value1 = 0
		currentPlayer++
	loop
	screen.cameraX = object[0].ixpos
	screen.cameraY = object[0].iypos
end function


function PlayerObject_RestorePowerup
	switch object[currentPlayer].value37
	case 0
		ResetObjectEntity(arrayPos0, TypeName[Blank Object], 0, 0, 0)
		break
	case 1
		ResetObjectEntity(arrayPos0, blueShieldType, 0, 0, 0)
		object[arrayPos0].priority = PRIORITY_ACTIVE
		object[arrayPos0].inkEffect = INK_ALPHA
		object[arrayPos0].alpha = 160
		break
	case 2
		ResetObjectEntity(arrayPos0, TypeName[Bubble Shield], 0, 0, 0)
		object[arrayPos0].priority = PRIORITY_ACTIVE
		break
	case 3
		ResetObjectEntity(arrayPos0, TypeName[Fire Shield], 0, 0, 0)
		object[arrayPos0].priority = PRIORITY_ACTIVE
		break
	case 4
		ResetObjectEntity(arrayPos0, TypeName[LightningShield], 0, 0, 0)
		object[arrayPos0].priority = PRIORITY_ACTIVE
		break
	case 5
		ResetObjectEntity(arrayPos0, goggleType, 0, 0, 0)
		object[arrayPos0].priority = PRIORITY_ACTIVE
		object[arrayPos0].value0 = currentPlayer
		object[arrayPos0].drawOrder = -1
	end switch
end function


function PlayerObject_HandleSuperPalSonic
	if PlayerObject_SuperState == 1
		PlayerObject_value3++
		if PlayerObject_value3 >= 4
			PlayerObject_value3 = 0
			PlayerObject_value2 += 4
			if PlayerObject_value2 >= 64
				PlayerObject_value2 = 24
			end if
		end if
	else
		PlayerObject_value3++
		if PlayerObject_value3 >= 8
			PlayerObject_value3 = 0
			PlayerObject_value2 -= 4
			if PlayerObject_value2 <= 0
				PlayerObject_value2 = 0
				PlayerObject_SuperState = 0
			end if
			if PlayerObject_value2 >= 24
				PlayerObject_value2 = 24
			end if
		end if
	end if
	temp1 = PlayerObject_value2
	GetTableValue(temp0, temp1, PlayerObject_SonicSuperPal)
	SetPaletteEntry(0, 2, temp0)
	GetTableValue(temp0, temp1, PlayerObject_SonicSuperAltPal)
	SetPaletteEntry(1, 2, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_SonicSuperPal)
	SetPaletteEntry(0, 3, temp0)
	GetTableValue(temp0, temp1, PlayerObject_SonicSuperAltPal)
	SetPaletteEntry(1, 3, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_SonicSuperPal)
	SetPaletteEntry(0, 4, temp0)
	GetTableValue(temp0, temp1, PlayerObject_SonicSuperAltPal)
	SetPaletteEntry(1, 4, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_SonicSuperPal)
	SetPaletteEntry(0, 5, temp0)
	GetTableValue(temp0, temp1, PlayerObject_SonicSuperAltPal)
	SetPaletteEntry(1, 5, temp0)
end function


function PlayerObject_HandleSuperPalTails
	if PlayerObject_SuperState == 1
		PlayerObject_value3++
		if PlayerObject_value3 >= 12
			PlayerObject_value3 = 0
			PlayerObject_value2 += 4
			if PlayerObject_value2 >= 24
				PlayerObject_value2 = 0
			end if
		end if
	else
		if PlayerObject_value2 > 12
			FlipSign(PlayerObject_value2)
			PlayerObject_value2 += 24
		end if
		PlayerObject_value3++
		if PlayerObject_value3 >= 12
			PlayerObject_value3 = 0
			PlayerObject_value2 -= 4
			if PlayerObject_value2 <= 0
				PlayerObject_value2 = 0
				PlayerObject_SuperState = 0
			end if
		end if
	end if
	temp1 = PlayerObject_value2
	GetTableValue(temp0, temp1, PlayerObject_TailsSuperPal)
	SetPaletteEntry(0, 13, temp0)
	GetTableValue(temp0, temp1, PlayerObject_TailsSuperAltPal)
	SetPaletteEntry(1, 13, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_TailsSuperPal)
	SetPaletteEntry(0, 17, temp0)
	GetTableValue(temp0, temp1, PlayerObject_TailsSuperAltPal)
	SetPaletteEntry(1, 17, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_TailsSuperPal)
	SetPaletteEntry(0, 18, temp0)
	GetTableValue(temp0, temp1, PlayerObject_TailsSuperAltPal)
	SetPaletteEntry(1, 18, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_TailsSuperPal)
	SetPaletteEntry(0, 16, temp0)
	GetTableValue(temp0, temp1, PlayerObject_TailsSuperAltPal)
	SetPaletteEntry(1, 16, temp0)
end function


function PlayerObject_HandleSuperPalKnux
	if PlayerObject_SuperState == 1
		PlayerObject_value3++
		if PlayerObject_value3 >= 12
			PlayerObject_value3 = 9
			PlayerObject_value2 += 3
			if PlayerObject_value2 >= 30
				PlayerObject_value3 = 0
				PlayerObject_value2 = 0
			end if
		end if
	else
		if PlayerObject_value2 > 15
			FlipSign(PlayerObject_value2)
			PlayerObject_value2 += 30
		end if
		PlayerObject_value3++
		if PlayerObject_value3 >= 12
			PlayerObject_value3 = 0
			PlayerObject_value2 -= 3
			if PlayerObject_value2 <= 0
				PlayerObject_value2 = 0
				PlayerObject_SuperState = 0
			end if
		end if
	end if
	temp1 = PlayerObject_value2
	GetTableValue(temp0, temp1, PlayerObject_KnuxSuperPal)
	SetPaletteEntry(0, 26, temp0)
	GetTableValue(temp0, temp1, PlayerObject_KnuxSuperAltPal)
	SetPaletteEntry(1, 26, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_KnuxSuperPal)
	SetPaletteEntry(0, 27, temp0)
	GetTableValue(temp0, temp1, PlayerObject_KnuxSuperAltPal)
	SetPaletteEntry(1, 27, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_KnuxSuperPal)
	SetPaletteEntry(0, 28, temp0)
	GetTableValue(temp0, temp1, PlayerObject_KnuxSuperAltPal)
	SetPaletteEntry(1, 28, temp0)
end function

function PlayerObject_HandleSuperPalAmy
	if PlayerObject_SuperState == 1
		PlayerObject_value3++
		if PlayerObject_value3 >= 12
			PlayerObject_value3 = 9
			PlayerObject_value2 += 4
			if PlayerObject_value2 >= 32
				PlayerObject_value3 = 0
				PlayerObject_value2 = 0
			end if
		end if
	else
		if PlayerObject_value2 > 20
			FlipSign(PlayerObject_value2)
			PlayerObject_value2 += 32
		end if
		PlayerObject_value3++
		if PlayerObject_value3 >= 16
			PlayerObject_value3 = 0
			PlayerObject_value2 -= 4
			if PlayerObject_value2 <= 0
				PlayerObject_value2 = 0
				PlayerObject_SuperState = 0
			end if
		end if
	end if
	temp1 = PlayerObject_value2
	GetTableValue(temp0, temp1, PlayerObject_AmySuperPal)
	SetPaletteEntry(0, 48, temp0)
	GetTableValue(temp0, temp1, PlayerObject_AmySuperAltPal)
	SetPaletteEntry(1, 48, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_AmySuperPal)
	SetPaletteEntry(0, 49, temp0)
	GetTableValue(temp0, temp1, PlayerObject_AmySuperAltPal)
	SetPaletteEntry(1, 49, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_AmySuperPal)
	SetPaletteEntry(0, 50, temp0)
	GetTableValue(temp0, temp1, PlayerObject_AmySuperAltPal)
	SetPaletteEntry(1, 50, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_AmySuperPal)
	SetPaletteEntry(0, 51, temp0)
	GetTableValue(temp0, temp1, PlayerObject_AmySuperAltPal)
	SetPaletteEntry(1, 51, temp0)
end function


function PlayerObject_HandleSuperPalShadow
	if PlayerObject_SuperState == 1
		PlayerObject_value3++
		if PlayerObject_value3 >= 4
			PlayerObject_value3 = 0
			PlayerObject_value2 += 4
			if PlayerObject_value2 >= 64
				PlayerObject_value2 = 24
			end if
		end if
	else
		PlayerObject_value3++
		if PlayerObject_value3 >= 8
			PlayerObject_value3 = 0
			PlayerObject_value2 -= 4
			if PlayerObject_value2 <= 0
				PlayerObject_value2 = 0
				PlayerObject_SuperState = 0
			end if
			if PlayerObject_value2 >= 24
				PlayerObject_value2 = 24
			end if
		end if
	end if
	temp1 = PlayerObject_value2
	GetTableValue(temp0, temp1, PlayerObject_ShadowSuperPal)
	SetPaletteEntry(0, 55, temp0)
	GetTableValue(temp0, temp1, PlayerObject_ShadowSuperAltPal)
	SetPaletteEntry(1, 55, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_ShadowSuperPal)
	SetPaletteEntry(0, 56, temp0)
	GetTableValue(temp0, temp1, PlayerObject_ShadowSuperAltPal)
	SetPaletteEntry(1, 56, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_ShadowSuperPal)
	SetPaletteEntry(0, 57, temp0)
	GetTableValue(temp0, temp1, PlayerObject_ShadowSuperAltPal)
	SetPaletteEntry(1, 57, temp0)
	temp1++
	GetTableValue(temp0, temp1, PlayerObject_ShadowSuperPal)
	SetPaletteEntry(0, 58, temp0)
	GetTableValue(temp0, temp1, PlayerObject_ShadowSuperAltPal)
	SetPaletteEntry(1, 58, temp0)
end function


function PlayerObject_SwapPhysics
	switch stage.playerListPos
	case 0
	case 3
		temp0 = PlayerObject_SonicPhysicsTable
		break
	case 1
		temp0 = PlayerObject_TailsPhysicsTable
		break
	case 2
		temp0 = PlayerObject_KnuxPhysicsTable
		break
	case 5
		temp0 = PlayerObject_AmyPhysicsTable
		break
	case 6
		temp0 = PlayerObject_ShadowPhysicsTable
		break		
	end switch
	temp1 = 0
	temp2 = 0
	if stage.state != 3
		temp3 = object[currentPlayer].ypos
		temp3 >>= 16
		CheckGreater(temp3, stage.waterLevel)
		temp4 = checkResult
		CheckNotEqual(object[currentPlayer].type, TypeName[Debug Mode])
		temp4 &= checkResult
		if temp4 == 1
			SetBit(temp1, 0, 1)
			object[currentPlayer].value25 = 0x1000
		else
			object[currentPlayer].value25 = 0x3800
		end if
		if PlayerObject_SuperState == 1
			SetBit(temp1, 1, 1)
			temp2 = 2
		end if
		if object[currentPlayer].value6 > 0
			SetBit(temp1, 2, 1)
			temp2 = 1
		end if
		temp1 <<= 3
	end if
	GetTableValue(object[currentPlayer].value20, temp1, temp0)
	temp1++
	GetTableValue(object[currentPlayer].value21, temp1, temp0)
	object[currentPlayer].value22 = object[currentPlayer].value21
	object[currentPlayer].value22 >>= temp2
	temp1++
	GetTableValue(object[currentPlayer].value23, temp1, temp0)
	temp1++
	//GetTableValue(object[currentPlayer].value24, temp1, temp0)
	temp1++
	GetTableValue(object[currentPlayer].value9, temp1, temp0)
	temp1++
	GetTableValue(object[currentPlayer].value29, temp1, temp0)
	temp1++
	GetTableValue(object[currentPlayer].value27, temp1, temp0)
	temp1++
	GetTableValue(object[currentPlayer].value28, temp1, temp0)
end function


function PlayerObject_ProcessSuperForms
	if PlayerObject_SuperState != 0
		switch stage.playerListPos
		case 0
		case 3
			CallFunction(PlayerObject_HandleSuperPalSonic)
			break
		case 1
			CallFunction(PlayerObject_HandleSuperPalTails)
			break
		case 2
			CallFunction(PlayerObject_HandleSuperPalKnux)
			break
		case 5
			CallFunction(PlayerObject_HandleSuperPalAmy)
			break
		case 6
			CallFunction(PlayerObject_HandleSuperPalShadow)
			break			
		end switch
	end if
	if PlayerObject_SuperState == 1
		player.invincible = 60
		PlayerObject_value1++
		if PlayerObject_value1 == 60
			PlayerObject_value1 = 0
			player.rings--
			if player.rings == 0
				PlayerObject_SuperState = 2
			end if
		end if
	end if
	if PlayerObject_SuperState == 2
		CallFunction(PlayerObject_EndSuper)
	end if
end function

function PlayerObject_EndSuper
	if stage.playerListPos == 0
		LoadAnimation("Sonic.ani")
	end if
	if stage.playerListPos == 6
		LoadAnimation("Shadow.ani")
	end if	
	if music.currentTrack == 7
		PlayMusic(0)
	end if
	if saved.Supermusic == 6
		if music.currentTrack == 2
			PlayMusic(0)
		end if
	end if
	if saved.Supermusic == 7
		if player.speedShoes < 1
			CallFunction(SlowDownMusic)
		end if
	end if
	player.invincible = 0
	if object.state != PlayerObject_Death
		if object.state != PlayerObject_Drown
			currentPlayer = object.entityPos
			arrayPos0 = currentPlayer
			arrayPos0 += playerCount
			CallFunction(PlayerObject_RestorePowerup)
			player.invulnerable = 60
		end if
	end if
	PlayerObject_SuperState = 3
	CallFunction(PlayerObject_SwapPhysics)
	if SuperTimeAttack == 1
		if stage.timeEnabled == 1
			ResetObjectEntity(11, TypeName[Title Card], 0, 0, 0)
			object[11].state = 10
			object[11].priority = PRIORITY_ACTIVE
			object[11].drawOrder = 6
			player.invincible = 80
			screen.cameraEnabled = 0
		end if
	end if
end function


function PlayerObject_CheckHit
	CheckEqual(object[currentPlayer].animation, ANI_JUMPING)
	temp0 = checkResult
	CheckEqual(object[currentPlayer].animation, ANI_SPINDASH)
	temp0 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_GLIDING)
	temp0 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_GLIDING_STOP)
	temp0 |= checkResult
	CheckNotEqual(object[currentPlayer].value7, 0)
	temp0 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLYING)
	temp1 = checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLYINGTIRED)
	temp1 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLY_LIFT_UP)
	temp1 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLY_LIFT_DOWN)
	temp1 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLY_LIFT_TIRED)
	temp1 |= checkResult
		CheckEqual(object[currentPlayer].animation, ANI_HAMMER_JUMP)
		temp0 |= checkResult
		CheckEqual(object[currentPlayer].animation, ANI_HAMMER_SPEEN)
		temp0 |= checkResult
	if temp1 == 1
		CheckGreater(object[currentPlayer].ypos, object.ypos)
		temp0 |= checkResult
	end if


	if temp0 == 1
		FlipSign(object[currentPlayer].xvel)
		object[currentPlayer].xvel >>= 1
		object[currentPlayer].speed = object[currentPlayer].xvel
		FlipSign(object[currentPlayer].yvel)
		object[currentPlayer].yvel >>= 1
		if object[currentPlayer].animation == ANI_GLIDING
			object[currentPlayer].value1 = 0
			object[currentPlayer].animation = ANI_GLIDING_DROP
			object[currentPlayer].state = PlayerObject_KnuxGlideDrop
		end if
		checkResult = 1
	else
		if object[currentPlayer].state != PlayerObject_Death
			if object[currentPlayer].value7 == 0
				if object[currentPlayer].value8 == 0
					object[currentPlayer].state = PlayerObject_Hurt
					if object[currentPlayer].xpos > object.xpos
						object[currentPlayer].speed = 0x20000
					else
						object[currentPlayer].speed = -0x20000
					end if
				end if
			end if
		end if
		checkResult = 0
	end if
end function

function PlayerObject_BadnikBreak
	CheckEqual(object[currentPlayer].animation, ANI_JUMPING)
	temp0 = checkResult
	CheckEqual(object[currentPlayer].animation, ANI_SPINDASH)
	temp0 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_GLIDING)
	temp0 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_GLIDING_STOP)
	temp0 |= checkResult
	CheckNotEqual(object[currentPlayer].value7, 0)
	temp0 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLYING)
	temp1 = checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLYINGTIRED)
	temp1 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLY_LIFT_UP)
	temp1 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLY_LIFT_DOWN)
	temp1 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLY_LIFT_TIRED)
	temp1 |= checkResult
		CheckEqual(object[currentPlayer].animation, ANI_HAMMER_JUMP)
		temp0 |= checkResult
		CheckEqual(object[currentPlayer].animation, ANI_HAMMER_SPEEN)
		temp0 |= checkResult
	if temp1 == 1
		CheckGreater(object[currentPlayer].ypos, object.ypos)
		temp0 |= checkResult
	end if

	
	if temp0 == 1
		ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, object.xpos, object.ypos)
		Rand(checkResult, 32)
		if checkResult > 15
			CreateTempObject(animalType1, TypeName[Blank Object], object.xpos, object.ypos)
		else
			CreateTempObject(animalType2, TypeName[Blank Object], object.xpos, object.ypos)
		end if
		object[tempObjectPos].priority = PRIORITY_UNKNOWN
		CreateTempObject(TypeName[Smoke Puff], 0, object.xpos, object.ypos)
		object[tempObjectPos].drawOrder = 4
		CreateTempObject(TypeName[Object Score], object[currentPlayer].value19, object.xpos, object.ypos)
		object[tempObjectPos].drawOrder = 4
		PlaySfx(SfxName[Destroy], 0)
		if object[currentPlayer].yvel > 0
			if object[currentPlayer].ypos >= object.ypos
				object[currentPlayer].yvel -= 0x10000
			else
				object[currentPlayer].yvel += object[currentPlayer].value25
				object[currentPlayer].yvel += object[currentPlayer].value25
				FlipSign(object[currentPlayer].yvel)
			end if
		else
			object[currentPlayer].yvel += 0x10000
		end if
		if options.competition == 0
			temp0 = currentPlayer
			currentPlayer = 0
		end if
		if stage.debugMode == 0
			saveRAM[999]++
		end if		
		switch object[currentPlayer].value19
		case 0
			player.score += 100
			break
		case 1
			player.score += 200
			break
		case 2
			player.score += 500
			break
		case 3
		case 4
		case 5
		case 6
		case 7
		case 8
		case 9
		case 10
		case 11
		case 12
		case 13
		case 14
			player.score += 1000
			break
		case 15
			player.score += 0x2710
			break
		end switch
		if object[currentPlayer].value19 < 15
			object[currentPlayer].value19++
		end if
		if options.competition == 0
			currentPlayer = temp0
		end if
	else
		if object[currentPlayer].state != PlayerObject_Death
			if object[currentPlayer].value7 == 0
				if object[currentPlayer].value8 == 0
					object[currentPlayer].state = PlayerObject_Hurt
					if object[currentPlayer].xpos > object.xpos
						object[currentPlayer].speed = 0x20000
					else
						object[currentPlayer].speed = -0x20000
					end if
				end if
			end if
		end if
	end if
end function


function PlayerObject_Hit
	if object[currentPlayer].state != PlayerObject_Death
		arrayPos0 = object[currentPlayer].entityPos
		arrayPos0 += playerCount
		if object[currentPlayer].value7 == 0
			if object[currentPlayer].value8 == 0
				object[currentPlayer].state = PlayerObject_Hurt
				if object[currentPlayer].xpos > object.xpos
					object[currentPlayer].speed = 0x20000
				else
					object[currentPlayer].speed = -0x20000
				end if
			end if
		end if
	end if
end function


function PlayerObject_FireHit
	if object[currentPlayer].value37 != 3
		if object[currentPlayer].state != PlayerObject_Death
			arrayPos0 = object[currentPlayer].entityPos
			arrayPos0 += playerCount
			if object[currentPlayer].value7 == 0
				if object[currentPlayer].value8 == 0
					object[currentPlayer].state = PlayerObject_Hurt
					if object[currentPlayer].xpos > object.xpos
						object[currentPlayer].speed = 0x20000
					else
						object[currentPlayer].speed = -0x20000
					end if
				end if
			end if
		end if
	end if
end function


function PlayerObject_LightningHit
	if object[currentPlayer].value37 != 4
		if object[currentPlayer].state != PlayerObject_Death
			arrayPos0 = object[currentPlayer].entityPos
			arrayPos0 += playerCount
			if object[currentPlayer].value7 == 0
				if object[currentPlayer].value8 == 0
					object[currentPlayer].state = PlayerObject_Hurt
					if object[currentPlayer].xpos > object.xpos
						object[currentPlayer].speed = 0x20000
					else
						object[currentPlayer].speed = -0x20000
					end if
				end if
			end if
		end if
	end if
end function


function PlayerObject_ProjectileHit
	//if object[currentPlayer].value37 > 1
	
	arrayPos0 = currentPlayer
	arrayPos0 += playerCount
	arrayPos0 += playerCount
	CheckEqual(object[arrayPos0].type, TypeName[Insta Shield])
	temp2 = checkResult
	CheckEqual(object[arrayPos0].propertyValue, 0)
	temp2 &= checkResult
	CheckGreater(object[currentPlayer].value37, 1)
	temp2 |= checkResult

	CheckEqual(object[currentPlayer].animation, ANI_FLYING)
	temp1 = checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLYINGTIRED)
	temp1 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLY_LIFT_UP)
	temp1 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLY_LIFT_DOWN)
	temp1 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_FLY_LIFT_TIRED)
	temp1 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_HAMMER_SPEEN)
	temp1 |= checkResult
	CheckEqual(object[currentPlayer].animation, ANI_HAMMER_JUMP)
	temp1 |= checkResult
	if temp1 == 1
		CheckGreater(object[currentPlayer].ypos, object.ypos)
		temp2 |= checkResult
	end if
	
	CheckEqual(object[currentPlayer].animation, ANI_GLIDING)
	if checkResult ==1
		if object[currentPlayer].state == PlayerObject_KnuxGlideRight
			CheckLower(object[currentPlayer].xpos, object.xpos)
			temp2 |= checkResult
		else
			if object[currentPlayer].state == PlayerObject_KnuxGlideLeft
				CheckGreater(object[currentPlayer].xpos, object.xpos)
				temp2 |= checkResult
			end if
		end if
	end if
	
	if temp2 == 1
		temp0 = object[currentPlayer].xpos
		temp0 -= object.xpos
		temp1 = object[currentPlayer].ypos
		temp1 -= object.ypos
		ATan2(temp2, temp0, temp1)
		Sin256(temp0, temp2)
		Cos256(temp1, temp2)
		object.xvel = temp1
		object.xvel *= -0x800
		object.yvel = temp0
		object.yvel *= -0x800
	else
		if object[currentPlayer].state != PlayerObject_Death
			arrayPos0 = object[currentPlayer].entityPos
			arrayPos0 += playerCount
			if object[currentPlayer].value7 == 0
				if object[currentPlayer].value8 == 0
					object[currentPlayer].state = PlayerObject_Hurt
					if object[currentPlayer].xpos > object.xpos
						object[currentPlayer].speed = 0x20000
					else
						object[currentPlayer].speed = -0x20000
					end if
				end if
			end if
		end if
	end if
end function


function PlayerObject_SpikeHit
	if object[currentPlayer].state != PlayerObject_Death
		arrayPos0 = object[currentPlayer].entityPos
		arrayPos0 += playerCount
		if object[currentPlayer].value7 == 0
			if object[currentPlayer].state != PlayerObject_Hurt
				if object[currentPlayer].state != PlayerObject_Knockback
					temp0 = saved.spikeBehavior
					if options.attractMode == 1
						temp0 = 0
					end if
					CheckEqual(object[currentPlayer].value8, 0)
					temp0 |= checkResult
					if temp0 == 1
						if object[currentPlayer].value8 == 0
							object[currentPlayer].value8 = 2
						end if
						object[currentPlayer].state = PlayerObject_Hurt
						if object[currentPlayer].xpos > object.xpos
							object[currentPlayer].speed = 0x20000
						else
							object[currentPlayer].speed = -0x20000
						end if
					end if
				end if
			end if
		end if
	end if
end function


function PlayerObject_Kill
	if stage.playerListPos == 6
		if saved.ShadowFX == 1
			PlaySfx(SfxName[Shadow Hurt], 0)				
		else
			PlaySfx(SfxName[Hurt], 0)
		end if
	else
		PlaySfx(SfxName[Hurt], 0)
	end if
	object[currentPlayer].speed = 0
	object[currentPlayer].xvel = 0
	object[currentPlayer].yvel = -0x68000
	object[currentPlayer].state = PlayerObject_Death
	object[currentPlayer].animation = ANI_DYING
	object[currentPlayer].tileCollisions = 0
	object[currentPlayer].interaction = 0
	object[currentPlayer].value8 = 0
	object[currentPlayer].visible = 1
	object[currentPlayer].value18 = 6
	if currentPlayer == 0
		object[currentPlayer].priority = PRIORITY_ACTIVE_PAUSED
		if object[1].type == TypeName[Player 2 Object]
			object[1].priority = PRIORITY_ACTIVE_PAUSED
		end if
		screen.cameraEnabled = 0
		stage.pauseEnabled = 0
		stage.state = 3
	end if
	arrayPos0 = currentPlayer
	arrayPos0 += playerCount
	if object[arrayPos0].type == invincibilityType
		object[arrayPos0].propertyValue = 3
	end if
	object[arrayPos0].type = TypeName[Blank Object]
	object[currentPlayer].value37 = 0
end function


function PlayerObject_ProcessPlayer
	if saved.mobile == 1
		if options.attractMode == 0
			if object.controlMode == 0
				CheckTouchRect(0, 96, screen.xcenter, screen.ysize)
				if checkResult > -1
					arrayPos0 = checkResult
					temp0 = touchscreen[arrayPos0].xpos
					temp0 -= 56
					temp1 = touchscreen[arrayPos0].ypos
					temp1 -= 184
					ATan2(temp2, temp0, temp1)
					temp2 += 16
					temp2 &= 255
					temp2 >>= 5
					switch temp2
					case 0
						inputDown.right = true
						break
					case 1
						inputDown.right = true
						inputDown.down = true
						break
					case 2
						inputDown.down = true
						break
					case 3
						inputDown.down = true
						inputDown.left = true
						break
					case 4
						inputDown.left = true
						break
					case 5
						inputDown.left = true
						inputDown.up = true
						break
					case 6
						inputDown.up = true
						break
					case 7
						inputDown.up = true
						inputDown.right = true
						break
					end switch
				end if
				CheckTouchRect(screen.xcenter, 96, screen.xsize, 240)
				if checkResult > -1
					inputDown.buttonA = 1
				end if
				if touchJump == 0
					inputPress.buttonA |= inputDown.buttonA
				end if
				touchJump = inputDown.buttonA
				if stage.debugMode == 1
					CheckTouchRect(0, 0, 122, 56)
					if checkResult > -1
						inputDown.buttonB = 1
					end if
					if touchDebug == 0
						inputPress.buttonB |= inputDown.buttonB
					end if
					touchDebug = inputDown.buttonB
				end if
				temp0=screen.xsize
				temp0-=90
				CheckTouchRect(temp0, 0, screen.xsize, 40)
				if checkResult > -1
					inputPress.start = 1
				end if
				temp0 -= 37
				temp1 = screen.xsize
				temp1 -= 95
				CheckTouchRect(temp0, 0, temp1, 40)				
				if checkResult > -1
					inputDown.buttonY = 1
				end if
				if touchMisc == 0
					inputPress.buttonY |= inputDown.buttonY
				end if
				touchMisc = inputDown.buttonY
			end if
			if object[30].type == TypeName[Act Finish])
				CheckTouchRect(0, 0, screen.xsize, screen.ysize)
				if checkResult > -1
					inputDown.buttonC = 1
				end if
			end if
		else
			CheckTouchRect(0, 0, screen.xsize, screen.ysize)	
			if checkResult > -1
				inputPress.start = 1
			end if
		end if
	end if

	if options.attractMode == 0
		ProcessObjectControl()
	else
		//if credits.screen == 0
		temp4 = 0
		if inputPress.start == 1
			if PlayerObject_ReplayLength > 1
				PlayerObject_ReplayLength = 1
				temp4 = 1
			end if
		end if
		//end if
		if object.controlMode == 0
			PlayerObject_ReplayFrameCnt--
			if PlayerObject_ReplayFrameCnt < 1
				if PlayerObject_ReplayTablePos < PlayerObject_ReplaySize
					GetTableValue(temp0, PlayerObject_ReplayTablePos, PlayerObject_ReplayTable)
					GetBit(object.up, temp0, 0)
					GetBit(object.down, temp0, 1)
					GetBit(object.left, temp0, 2)
					GetBit(object.right, temp0, 3)
					GetBit(object.jumpPress, temp0, 4)
					GetBit(object.jumpHold, temp0, 5)
					PlayerObject_ReplayTablePos++
					GetTableValue(PlayerObject_ReplayFrameCnt, PlayerObject_ReplayTablePos, PlayerObject_ReplayTable)
					PlayerObject_ReplayTablePos++
				end if
			else
				if object.jumpPress == 1
					object.jumpPress = 0
				end if
			end if
			if PlayerObject_ReplayLength > 0
				PlayerObject_ReplayLength--
				if PlayerObject_ReplayLength < 1
					ResetObjectEntity(11, TypeName[Title Card], 0, 0, 0)
					object[11].state = 8
					if credits.screen > 0
						object[11].state += temp4
					end if
					object[11].priority = PRIORITY_ACTIVE
					object[11].drawOrder = 6
					player.invincible = 80
					screen.cameraEnabled = 0
				end if
			end if
		end if
	end if
	if player.speedShoes > 0
		player.speedShoes--
		if player.speedShoes < 1
			currentPlayer = object.entityPos
			CallFunction(PlayerObject_SwapPhysics)
			if SlowDownMusic != 0
				if PlayerObject_SuperState != 1
					CallFunction(SlowDownMusic)
				else
					if saved.Supermusic != 7
						CallFunction(SlowDownMusic)
					end if
				end if
			end if
			player.speedShoes = 0
		end if
	end if
	if object.state != PlayerObject_Knockback
		if player.invulnerable > 0
			player.invulnerable--
			GetBit(temp0, player.invulnerable, 2)
			if temp0 == 1
				object.visible = 0
			else
				object.visible = 1
			end if
		end if
	end if
	if player.invincible > 0
		player.invincible--
		if player.invincible == 0
			if music.currentTrack == 2
				PlayMusic(0)
			end if
			if object[+playerCount].type == invincibilityType
				currentPlayer = object.entityPos
				arrayPos0 = currentPlayer
				arrayPos0 += playerCount
				CallFunction(PlayerObject_RestorePowerup)
				player.invulnerable = 60
			end if
		end if
	end if
	if object.state != PlayerObject_LookingUp
		if object.state != PlayerObject_Crouching
			if object.lookPosY > 0
				object.lookPosY -= 2
			end if
			if object.lookPosY < 0
				object.lookPosY += 2
			end if
		end if
	end if
	if camera.lockTimer > 0
		camera.lockTimer--
		if camera.lockTimer == 0
			screen.cameraStyle = 0
		end if
	end if
	if object.state != PlayerObject_HandleTailsFlight
		if player.flightVelocity != 0
			if object.state != PlayerObject_HandleHammerSpin
				StopSfx(SfxName[Flying])
				StopSfx(SfxName[Tired])
				player.flightVelocity = 0
			end if
		end if
	end if
	if object.state != PlayerObject_ChaosBlast
		StopSfx(SfxName[Charge Lazer])
	end if	
end function


function PlayerObject_Blank
	checkResult = 0
end function


function PlayerObject_HandleRollAnimSpd
	if object.propertyValue == 1
		player.CustomRollAnimSpeed = 120
	else
		player.CustomRollAnimSpeed = object.speed
		if player.CustomRollAnimSpeed < 0
			FlipSign(player.CustomRollAnimSpeed)
		end if
		player.CustomRollAnimSpeed *= 240
		player.CustomRollAnimSpeed /= 0x60000
		player.CustomRollAnimSpeed += 48
	end if
end function


function PlayerObject_HandleWalkAnimSpd
	object.animationSpeed = object.speed
	if object.animationSpeed < 0
		FlipSign(object.animationSpeed)
	end if
	object.animationSpeed *= 60
	object.animationSpeed /= 0x60000
	object.animationSpeed += 20
end function


function PlayerObject_HandleRunAnimSpd
	object.animationSpeed = object.speed
	if object.animationSpeed < 0
		FlipSign(object.animationSpeed)
	end if
	object.animationSpeed *= 80
	object.animationSpeed /= 0x60000
end function

function PlayerObject_HandleMovement
	if object.controlLock > 0
		object.controlLock--
		Sin256(temp0, object.angle)
		temp0 *= 0x2000
		temp0 >>= 8
		object.speed += temp0
	else
		if object.left == 1
			temp0 = player.speedCap
			FlipSign(temp0)
			if object.speed > temp0
				if object.speed > 0
					if object.collisionMode == CMODE_FLOOR
						if object.speed > 0x40000
							player.skidding = 16
						end if
					end if
					if object.speed < player.minRollSpeed
						object.speed = player.minRollSpeed
						FlipSign(object.speed)
						player.skidding = 0
					else
						object.speed -= player.minRollSpeed
					end if
				else
					object.speed -= player.acceleration
					player.skidding = 0
				end if
			end if
			if object.speed <= 0
				object.direction = FLIP_X
			end if
		end if
		if object.right == 1
			if object.speed < player.speedCap
				if object.speed < 0
					if object.collisionMode == CMODE_FLOOR
						if object.speed < -0x40000
							player.skidding = 16
						end if
					end if
					temp0 = player.minRollSpeed
					FlipSign(temp0)
					if object.speed > temp0
						object.speed = player.minRollSpeed
						player.skidding = 0
					else
						object.speed += player.minRollSpeed
					end if
				else
					object.speed += player.acceleration
					player.skidding = 0
				end if
			end if
			if object.speed >= 0
				object.direction = FLIP_NONE
			end if
		end if
		temp0 = object.left
		temp0 |= object.right
		if temp0 == 0
			if object.speed > 0
				object.speed -= player.deceleration
				if object.speed < 0
					object.speed = 0
				end if
			else
				object.speed += player.deceleration
				if object.speed > 0
					object.speed = 0
				end if
			end if
			if object.speed > 0x2000
				Sin256(temp0, object.angle)
				temp0 *= 0x2000
				temp0 >>= 8
				object.speed += temp0
			end if
			if object.speed < -0x2000
				Sin256(temp0, object.angle)
				temp0 *= 0x2000
				temp0 >>= 8
				object.speed += temp0
			end if
			if object.angle > 192
				if object.angle < 228
					if object.speed > -0x10000
						if object.speed < 0x10000
							object.controlLock = 30
						end if
					end if
				end if
			end if
			if object.angle > 28
				if object.angle < 64
					if object.speed > -0x10000
						if object.speed < 0x10000
							object.controlLock = 30
						end if
					end if
				end if
			end if
		else
			Sin256(temp0, object.angle)
			temp0 *= 0x2000
			temp0 >>= 8
			object.speed += temp0
			if object.right == 1
				if object.left == 0
					if object.angle > 192
						if object.angle < 228
							if object.speed < 0x28000
								if object.speed > -0x20000
									object.controlLock = 30
								end if
							end if
						end if
					end if
				end if
			else
				if object.left == 1
					if object.angle > 28
						if object.angle < 64
							if object.speed > -0x28000
								if object.speed < 0x20000
									object.controlLock = 30
								end if
							end if
						end if
					end if
				end if
			end if
		end if
		if saved.speedCap == 1
			if options.attractMode == 0
				if object.left == 1
					temp0 = player.speedCap
					FlipSign(temp0)
					if object.speed < temp0
						object.speed = temp0
					end if
				end if
				if object.right == 1
					if object.speed > player.speedCap
						object.speed = player.speedCap
					end if
				end if
			end if
		end if
	end if
	switch object.collisionMode
	case 1
		if object.angle <= 192
			if object.speed > -0x20000
				if object.speed < 0x20000
					object.gravity = GRAVITY_AIR
					object.angle = 0
					object.collisionMode = CMODE_FLOOR
					object.speed = object.xvel
				end if
			end if
		end if
		break
	case 2
		if object.speed > -0x20000
			if object.speed < 0x20000
				object.gravity = GRAVITY_AIR
				object.angle = 0
				object.collisionMode = CMODE_FLOOR
				object.speed = object.xvel
			end if
		end if
		break
	case 3
		if object.angle >= 64
			if object.speed > -0x20000
				if object.speed < 0x20000
					object.gravity = GRAVITY_AIR
					object.angle = 0
					object.collisionMode = CMODE_FLOOR
					object.speed = object.xvel
				end if
			end if
		end if
		break
	end switch
end function


function PlayerObject_HandleAirAcceleration
	if object.yvel > -0x40000
		if object.yvel < 0
			temp0 = object.speed
			temp0 >>= 5
			object.speed -= temp0
		end if
	end if
	temp0 = player.speedCap
	FlipSign(temp0)
	if object.speed > temp0
		if object.left == 1
			object.speed -= player.airAcceleration
			object.direction = FLIP_X
		end if
	else
		if object.left == 1
			object.direction = FLIP_X
		end if
	end if
	if object.speed < player.speedCap
		if object.right == 1
			object.speed += player.airAcceleration
			object.direction = FLIP_NONE
		end if
	else
		if object.right == 1
			object.direction = FLIP_NONE
		end if
	end if
	if saved.airSpeedCap == 1
		if options.attractMode == 0
			if object.left == 1
				temp0 = player.speedCap
				FlipSign(temp0)
				if object.speed < temp0
					object.speed = temp0
				end if
			end if
			if object.right == 1
				if object.speed > player.speedCap
					object.speed = player.speedCap
				end if
			end if
		end if
	end if
end function


function PlayerObject_HandleRolling	
	if object.right == 1
		if object.speed < 0
			object.speed += player.rollingDecelerationP
		end if
	end if
	if object.left == 1
		if object.speed > 0
			object.speed -= player.rollingDecelerationP
		end if
	end if
	temp1 = object.speed
	if object.speed > 0
		object.speed -= player.rollingDecelerationA
		Sin256(temp0, object.angle)
		if temp0 > 0
			Sin256(temp0, object.angle)
			temp0 *= 0x5000
		else
			Sin256(temp0, object.angle)
			temp0 *= 0x1400
		end if
		temp0 >>= 8
		object.speed += temp0
		if object.speed > 0x120000
			object.speed = 0x120000
		end if
	else
		object.speed += player.rollingDecelerationA
		Sin256(temp0, object.angle)
		if temp0 < 0
			Sin256(temp0, object.angle)
			temp0 *= 0x5000
		else
			Sin256(temp0, object.angle)
			temp0 *= 0x1400
		end if
		temp0 >>= 8
		object.speed += temp0
		if object.speed < -0x120000
			object.speed = -0x120000
		end if
	end if
	switch object.collisionMode
	case 0
	case 2
		if temp1 > 0
			if object.speed < 0
				object.speed = 0
				object.state = PlayerObject_HandleGround
			end if
		else
			if object.speed > 0
				object.speed = 0
				object.state = PlayerObject_HandleGround
			end if
		end if
		break
	case 1
		if object.angle < 193
			if temp1 > 0
				if object.speed < 0x20000
					object.gravity = GRAVITY_AIR
					object.xvel = 0
					object.speed = 0
				end if
			end if
		end if
		break
	case 3
		if object.angle > 63
			if temp1 < 0
				if object.speed > -0x20000
					object.gravity = GRAVITY_AIR
					object.xvel = 0
					object.speed = 0
				end if
			end if
		end if
		break
	end switch
end function


function PlayerObject_HandleAirMovement
	object.scrollTracking = 1
	object.yvel += player.gravityValue
	if object.yvel < player.jumpStrength
		if object.jumpHold == 0
			if object.value1 > 0
				object.yvel = player.jumpStrength
				temp0 = object.speed
				temp0 >>= 5
				object.speed -= temp0
			end if
		end if
	end if
	object.xvel = object.speed
	
	object.collisionMode = CMODE_FLOOR
	if object.animation == ANI_JUMPING
		object.animationSpeed = player.CustomRollAnimSpeed
	end if
end function


function PlayerObject_ResetOnFloor
	object.scrollTracking = 0
	Cos256(temp0, object.angle)
	temp0 *= object.speed
	temp0 >>= 8
	object.xvel = temp0
	Sin256(temp0, object.angle)
	temp0 *= object.speed
	temp0 >>= 8
	object.yvel = temp0
end function


function PlayerObject_StartJump	
	temp1 = 0
	if object.collisionMode == CMODE_FLOOR
		temp6 = object.xpos
		temp7 = object.ypos
		temp0 = object.collisionTop
		temp0 -= 2
		ObjectTileCollision(CSIDE_ROOF, 0, temp0, object.collisionPlane)
		temp1 = checkResult
		object.xpos = temp6
		object.ypos = temp7
		temp0 = object.collisionBottom
		if object.animation != ANI_JUMPING
			if object.propertyValue != 5
				object.iypos -= player.jumpOffset
				temp0 += player.jumpOffset
			end if
		end if
		ObjectTileCollision(CSIDE_FLOOR, 0, temp0, object.collisionPlane)
	end if
	if temp1 == 0
		temp2 = 0
		if object.propertyValue == 5
			if object.up == 1
				if saved.AmyMoveset == 0
					temp2 = 1
				end if
			end if
		end if
		object.controlLock = 0
		object.gravity = GRAVITY_AIR
		temp1 = player.jumpVelocity
		temp1 += player.gravityValue
		Sin256(object.xvel, object.angle)
		object.xvel *= temp1
		Cos256(temp0, object.angle)
		temp0 *= object.speed
		object.xvel += temp0
		object.xvel >>= 8
		Sin256(object.yvel, object.angle)
		object.yvel *= object.speed
		Cos256(temp0, object.angle)
		temp0 *= temp1
		object.yvel -= temp0
		object.yvel >>= 8
		object.speed = object.xvel
		object.scrollTracking = 1
		if temp2 == 1
			if saved.AmyMoveset == 0
                object.collisionMode = CMODE_FLOOR
				temp0 = object.angle
				temp0 >>= 6
				switch temp0
					case 1
					case 2
						object.yvel -= player.jumpStrength
						player.animationReserve = ANI_HAMMER_JUMP
						break
					default
						object.yvel += player.jumpStrength
						player.animationReserve = ANI_FALL
						break
				end switch
				object.animation = ANI_HAMMER_JUMP
				PlaySfx(SfxName[Thud], 0)
				object.value1 = 0
				object.state = PlayerObject_HandleAir
			end if
		else
            object.angle = 0
            object.collisionMode = CMODE_FLOOR
		    object.value1 = 1
			object.animation = ANI_JUMPING
			if object.propertyValue == 5
				if saved.AmyMoveset == 1
					object.animation = 11
					object.value10 = ANI_FALL
				end if
			end if
			
			CallFunction(PlayerObject_HandleRollAnimSpd)
			if object.state == PlayerObject_HandleRoll
				if saved.Jumplock == 1
					object.state = PlayerObject_RollingJump
				else
					if options.attractMode == 1
						object.state = PlayerObject_RollingJump
					else
						object.state = PlayerObject_HandleAir
					end if
				end if	
			else
				object.state = PlayerObject_HandleAir
			end if
			PlaySfx(SfxName[Jump], 0)
			player.doubleJumpState = 1
		end if

		player.collisionEnabled = 1
	end if
	if stage.playerListPos == 6
		switch saved.ShadowJump
			case 0
				//play spark the electric jester
				break
			case 1
				PlaySfx(SfxName[ShadowJump], 0)
				StopSfx(SfxName[Jump])
				break
			case 2
				PlaySfx(SfxName[ModernJump], 0)
				StopSfx(SfxName[Jump])
				break
		end switch
	end if	
end function


function PlayerObject_StartSpindash
	object.state = PlayerObject_HandleSpindash
	object.animation = ANI_SPINDASH
	object.value2 = 0
	PlaySfx(SfxName[Charge], 0)
	CreateTempObject(TypeName[Dust Puff], object.entityPos, object.xpos, object.ypos)
	object[tempObjectPos].iypos = object.collisionBottom
	object[tempObjectPos].ypos += object.ypos
	object[tempObjectPos].frame = 4
	object[tempObjectPos].drawOrder = 4
	object[tempObjectPos].direction = object.direction
end function


function PlayerObject_StartSpindashCD
	object.state = PlayerObject_HandleSpindashCD
	object.animation = ANI_JUMPING
	object.value2 = 0
	object.iypos -= player.jumpOffset
	PlaySfx(SfxName[Charge], 0)
	CreateTempObject(TypeName[Dust Puff], object.entityPos, object.xpos, object.ypos)
	object[tempObjectPos].iypos = object.collisionBottom
	object[tempObjectPos].ypos += object.ypos
	object[tempObjectPos].frame = 4
	object[tempObjectPos].drawOrder = 4
	object[tempObjectPos].direction = object.direction
end function


function PlayerObject_Transforming
	player.collisionEnabled = 1
	object.value1--
	if object.value1 == 0
		object.state = PlayerObject_HandleAir
		object.animation = ANI_WALKING
	end if
end function


function PlayerObject_SuperTransform
	if stage.timeEnabled == 1
		if player.invulnerable == 0
			arrayPos0 = currentPlayer
			arrayPos0 += playerCount
			ResetObjectEntity(arrayPos0, TypeName[Super Spark], 0, object[0].xpos, object[0].ypos)
			object[arrayPos0].priority = PRIORITY_ACTIVE
			if stage.playerListPos == 6
				if saved.ShadowFX == 1
					PlaySfx(SfxName[Shadow Transform], 0)			
				end if	
			end if
			PlaySfx(SfxName[Transform], 0)
				
			if music.currentTrack != 4
				switch saved.Supermusic
					case 0
						if music.currentTrack != 0
							PlayMusic(0)
						end if
						break
					case 6
						if music.currentTrack != 2
							PlayMusic(2)
						end if
						break
					case 7
						if music.currentTrack != 0
							PlayMusic(0)
						end if
						if object[currentPlayer].value6 < 1
							CallFunction(SpeedUpMusic)
						end if
						break
					default
						PlayMusic(7)
						break
				end switch
			end if
			PlayerObject_SuperState = 1
			object[currentPlayer].value7 = 60
			object[currentPlayer].value8 = 0
			object[currentPlayer].visible = 1
			CallFunction(PlayerObject_SwapPhysics)
			if stage.playerListPos == 0
				LoadAnimation("SuperSonic.ani")
				if saveRAM[411] == 1
					if stage.debugMode == 0
						achievement.trigger = 14
					end if
				end if
			end if
			if stage.playerListPos == 6
				LoadAnimation("SuperShadow.ani")
			end if			
			if stage.playerListPos == 1
				if saved.gogoplus > 0
					temp0 = 0
					arrayPos0 = 13
					while temp0 < 4
						Rand(temp1, 201)
						temp1 -= 100
						temp1 += screen.xoffset
						temp1 -= screen.xcenter
						//temp1 += screen.xcenter
						temp1 <<= 16
					
						Rand(temp2, 201)
						temp2 -= 100
						temp2 += screen.yoffset
						temp2 -= screen.ycenter
						//temp2 += screen.ycenter
						temp2 <<= 16
						
						ResetObjectEntity(arrayPos0, TypeName[Insta Shield], 2, temp1, temp2)
						object[arrayPos0].priority = PRIORITY_ACTIVE
						object[arrayPos0].angle = 64
						object[arrayPos0].angle *= temp0
						object[arrayPos0].drawOrder = 5
					arrayPos0++
					temp0++
					loop
				end if
			end if
			object[currentPlayer].state = PlayerObject_Transforming
			object[currentPlayer].value34 = 1
			object[currentPlayer].animation = ANI_SUPER_TRANSFORM
			object[currentPlayer].value1 = 24
		end if
	end if
end function


function PlayerObject_BubbleBounce
	CallFunction(PlayerObject_HandleAirAcceleration)
	CheckNotEqual(player.shield, 2)
	temp0 = checkResult
	CheckNotEqual(player.invincible, 0)
	temp0 |= checkResult
	CheckEqual(PlayerObject_SuperState, 1)
	temp0 |= checkResult
	if temp0 == 1
		object.state = PlayerObject_HandleAir
	else
		if object.gravity == GRAVITY_AIR
			CallFunction(PlayerObject_HandleAirMovement)
		else
			player.doubleJumpState = 1
			object.gravity = GRAVITY_AIR
			if player.jumpVelocity == 0x38000
				temp1 = 0x40000
			else
				temp1 = 0x78000
			end if
			temp1 += player.gravityValue
			Sin256(object.xvel, object.angle)
			object.xvel *= temp1
			Cos256(temp0, object.angle)
			temp0 *= object.speed
			object.xvel += temp0
			object.xvel >>= 8
			Sin256(object.yvel, object.angle)
			object.yvel *= object.speed
			Cos256(temp0, object.angle)
			temp0 *= temp1
			object.yvel -= temp0
			object.yvel >>= 8
			object.speed = object.xvel
			object.scrollTracking = 1
			object.animation = ANI_JUMPING
			object.angle = 0
			object.collisionMode = CMODE_FLOOR
			object.value1 = 1
			CallFunction(PlayerObject_HandleRollAnimSpd)
			object.state = PlayerObject_HandleAir
			PlaySfx(SfxName[Bubble Bounce], 0)
			object[+playerCount].state = 4
		end if
	end if
end function

function PlayerObject_HandleShieldAbilities
	if object.entityPos == 0
		if saved.Dropdash == 1
			if options.attractMode == 0
				CheckNotEqual(player.invincible, 0)
				temp0 = checkResult
				CheckEqual(PlayerObject_SuperState, 1)
				temp0 |= checkResult
				CheckLower(player.shield, 2)
				temp0 |= checkResult
				CheckEqual(player.shield, 5)
				temp0 |= checkResult
				CheckGreater(player.dropDashCharge,0)
				temp0 |= checkResult
				if temp0 == 1
					CallFunction(PlayerObject_DropDash)
				end if
			end if
		end if
	end if
	if player.doubleJumpState == 1
		if inputPress.buttonY == 1
			CheckEqual(specialStage.emeralds, 127)
			temp0 = checkResult
			CheckGreater(player.rings, 49)
			temp0 &= checkResult
			CheckNotEqual(PlayerObject_SuperState, 1)
			temp0 &= checkResult
			CheckNotEqual(object[30].type, TypeName[Act Finish])
			temp0 &= checkResult
			CheckEqual(saved.superStates, 1)
			temp0 &= checkResult
			CheckEqual (player.invulnerable, 0)
			temp0 &= checkResult
			
			if temp0 == 1
				currentPlayer = object.entityPos
				CallFunction(PlayerObject_SuperTransform)
			end if
		end if
		//CheckEqual(stage.player2Enabled, 1)
		//temp4 = checkResult
		//CheckEqual(object.up, 1)
		//temp4 &= checkResult
		//if temp4 == 0
			if object.jumpPress == 1
				if PlayerObject_SuperState == 1
					if saved.gogoplus > 0
						if options.gameMode != 2
							player.doubleJumpState = 2
							ResetObjectEntity(13, TypeName[Insta Shield], 1, 0, 0)
							object[13].priority = PRIORITY_ACTIVE
							PlaySfx(SfxName[Release],0)
							
							temp5 = 0
							SetBit(temp5, 0, object.up)
							SetBit(temp5, 1, object.down)
							SetBit(temp5, 2, object.left)
							SetBit(temp5, 3, object.right)
							
							CheckNotEqual(temp5, 0)
							temp4 = checkResult
							CheckLower(temp5, 12)
							temp4 &= checkResult
							
							if temp4 == 1
								temp6 = temp5
								temp6 &= 3
								switch temp6
									case 1
										object.yvel = -0x80000
										break
									case 2
										object.yvel = 0x80000
										break
									default
										object.yvel = 0
										break
								end switch
								
								temp6 = temp5
								temp6 &= 12
								switch temp6
									case 4
										object.xvel = -0x80000
										break
									case 8
										object.xvel = 0x80000
										break
									default
										object.xvel = 0
										break
								end switch
								
								object.speed = object.xvel
								player.doubleJumpState = 2
								if camera.lockTimer == 0
									camera.lockTimer = 15
								end if
								screen.cameraStyle = 4
								if object.state == PlayerObject_RollingJump
									object.state = PlayerObject_HandleAir
								end if		
							else
								GetBit(temp0, object.direction, 0)
								if temp0 == 0
									object.xvel = 0x80000
								else
									object.xvel = -0x80000
								end if
								object.speed = object.xvel
								object.yvel = 0
								player.doubleJumpState = 2
								if camera.lockTimer == 0
									camera.lockTimer = 15
								end if
								screen.cameraStyle = 4
								if object.state == PlayerObject_RollingJump
									object.state = PlayerObject_HandleAir
								end if						
							end if
						end if
					end if
				end if
				
				CheckEqual(player.invincible, 0)
				temp0 = checkResult
				CheckNotEqual(PlayerObject_SuperState, 1)
				temp0 &= checkResult
				if temp0 == 1
					switch player.shield
					case 0
					case 5
						if saved.Instashield == 1
							if options.attractMode == 0
								PlaySfx(SfxName[Insta Shield], 0)
								//if object[+playerCount].type == TypeName[Blank Object]
									currentPlayer = object.entityPos
									arrayPos0 = currentPlayer
									arrayPos0 += playerCount
									arrayPos0 += playerCount
									ResetObjectEntity(arrayPos0, TypeName[Insta Shield], 0, 0, 0)
									object[arrayPos0].priority = PRIORITY_ACTIVE
									object[arrayPos0].value16 = object.entityPos
								//end if
								player.doubleJumpState = 2
								object[+playerCount].state = 1
								if object.state == PlayerObject_RollingJump
									object.state = PlayerObject_HandleAir
								end if
							end if
						end if
						break
					case 1
						break
					case 2
						PlaySfx(SfxName[Bubble Bounce], 0)
						object.yvel = 0x80000
						if saved.bubble == 0
							object.xvel = 0
						else
							object.xvel >>= 1
						end if
						object.speed = object.xvel
						player.doubleJumpState = 2
						object.state = PlayerObject_BubbleBounce
						object[+playerCount].state = 2
						break
					case 3
						PlaySfx(SfxName[Fire Dash], 0)
						GetBit(temp0, object.direction, 0)
						if temp0 == 0
							object.xvel = 0x80000
						else
							object.xvel = -0x80000
						end if
						object.speed = object.xvel
						object.yvel = 0
						player.doubleJumpState = 2
						camera.lockTimer = 15
						screen.cameraStyle = 4
						if object.state == PlayerObject_RollingJump
							object.state = PlayerObject_HandleAir
						end if
						object[+playerCount].state = 2
						object[+playerCount].direction = object.direction
						break
					case 4
						PlaySfx(SfxName[Lightning Jump], 0)
						object.yvel = -0x58000
						player.doubleJumpState = 2
						CreateTempObject(TypeName[Lightning Spark], 0, object.xpos, object.ypos)
						object[tempObjectPos].xvel = -0x20000
						object[tempObjectPos].yvel = -0x20000
						CreateTempObject(TypeName[Lightning Spark], 0, object.xpos, object.ypos)
						object[tempObjectPos].xvel = 0x20000
						object[tempObjectPos].yvel = -0x20000
						CreateTempObject(TypeName[Lightning Spark], 0, object.xpos, object.ypos)
						object[tempObjectPos].xvel = -0x20000
						object[tempObjectPos].yvel = 0x20000
						CreateTempObject(TypeName[Lightning Spark], 0, object.xpos, object.ypos)
						object[tempObjectPos].xvel = 0x20000
						object[tempObjectPos].yvel = 0x20000
						if object.state == PlayerObject_RollingJump
							object.state = PlayerObject_HandleAir
						end if
						break
					end switch
				end if
			end if
		//end if
	end if
end function

function PlayerObject_DropDash
	if player.doubleJumpState > 0
		if player.dropDashCharge > 0
			if object.jumpHold==1
				player.dropDashCharge++
				if player.dropDashCharge == 21
					PlaySfx(SfxName[Drop Dash], 0)
					object.value2 = 0
				end if
				
			else
				object.value1 = 0
				player.dropDashCharge = 0
				if player.dropDashCharge < 21
					object.value2 = 0
				end if
			end if
		else
			if object.jumpPress == 1
				player.dropDashCharge = 2
			end if
		end if
	end if
end function

function PlayerObject_StartHop
		PlaySfx(SfxName[Flying], 0)
		object.controlLock = 0
		object.gravity = GRAVITY_AIR
		
		if object.direction == FLIP_X
			object.xvel -= 0x50000
		else
			object.xvel += 0x50000
		end if	
		
		object.yvel = -0x30000
		
		object.speed = object.xvel
		object.scrollTracking = 1
		object.animation = ANI_HAMMER_SPEEN
		object.angle = 0
		object.collisionMode = CMODE_FLOOR
		object.value1 = 1
		object.state = PlayerObject_HandleAir

		object.value34 = 1
		object.value35 = 1
		player.doubleJumpState = 2
end function

function PlayerObject_StartSecondJump	
	temp1 = 0
	if object.collisionMode == CMODE_FLOOR
		temp6 = object.xpos
		temp7 = object.ypos
		temp0 = object.collisionTop
		temp0 -= 2
		ObjectTileCollision(CSIDE_ROOF, 0, temp0, object.collisionPlane)
		temp1 = checkResult
		object.xpos = temp6
		object.ypos = temp7
		temp0 = object.collisionBottom
		if object.animation != ANI_JUMPING
			if stage.playerListPos != 5
				object.iypos -= player.jumpOffset
				temp0 += player.jumpOffset
			end if
		end if
		ObjectTileCollision(CSIDE_FLOOR, 0, temp0, object.collisionPlane)
	end if
	if temp1 == 0
		temp2 = 1
		object.controlLock = 0
		object.gravity = GRAVITY_AIR
		temp1 = player.jumpVelocity
		temp1 += player.gravityValue
		Sin256(object.xvel, object.angle)
		object.xvel *= temp1
		Cos256(temp0, object.angle)
		temp0 *= object.speed
		object.xvel += temp0
		object.xvel >>= 8
		Sin256(object.yvel, object.angle)
		object.yvel *= object.speed
		Cos256(temp0, object.angle)
		temp0 *= temp1
		object.yvel -= temp0
		object.yvel >>= 8
		object.speed = object.xvel
		object.scrollTracking = 1
		object.angle = 0
		object.collisionMode = CMODE_FLOOR
		object.value1 = 1
		if temp2 == 1
			object.animation = ANI_HAMMER_JUMP
			PlaySfx(SfxName[Thud], 0)
			object.value1 = 0
			object.state = PlayerObject_HandleAir
			player.animationReserve = 52
		end if
		player.collisionEnabled = 1
		player.doubleJumpState = 2
	end if
end function


function PlayerObject_StartHammerSpin
	if player.doubleJumpState == 1
		if inputPress.buttonY == 1
			CheckEqual(specialStage.emeralds, 127)
			temp0 = checkResult
			CheckGreater(player.rings, 49)
			temp0 &= checkResult
			CheckNotEqual(PlayerObject_SuperState, 1)
			temp0 &= checkResult
			CheckNotEqual(object[30].type, TypeName[Act Finish])
			temp0 &= checkResult
			CheckEqual(saved.superStates, 1)
			temp0 &= checkResult
			CheckEqual (player.invulnerable, 0)
			temp0 &= checkResult
			if temp0 == 1
				currentPlayer = object.entityPos
				CallFunction(PlayerObject_SuperTransform)
			end if
		end if
		if object.jumpPress == 1
			if saved.AmyMoveset == 0
				object.value1 = 0
				object.state = PlayerObject_HandleHammerSpin
				player.flightVelocity = 0x800
				object.yvel = 0
				if player.gravityValue == 0x3800
					PlaySfx(SfxName[Flying], 1)
				end if
				object.animation = ANI_HAMMER_SPEEN
			end if
		end if
	end if
end function

function PlayerObject_HandleHammerSpin
	CallFunction(PlayerObject_HandleAirAcceleration)
	if object.gravity == GRAVITY_AIR
		object.xvel = object.speed
		if object.yvel < -0x10000
			player.flightVelocity = 0x800
		else
			if object.yvel < 1
				if object.value2 < 60
					object.value2++
				else
					player.flightVelocity = 0x800
				end if
			end if
		end if
		object.yvel += player.flightVelocity
		if object.ypos < 0x100000
			if object.yvel < 0
				object.yvel = 0
			end if
		end if
		object.value1++
		CheckLower(object.value1, 180)
		temp0 = checkResult
		CheckEqual(object.jumpHold, 1)
		temp0 &= checkResult
		if temp0 == 0
			object.animation = ANI_HAMMER_SPEEN
			object.state = PlayerObject_HandleAir
		end if
	else
		object.animation = ANI_WALKING
		object.state = PlayerObject_HandleGround
		CallFunction(PlayerObject_ResetOnFloor)
	end if

	//Fly Cancel

	if saved.FlightCancel == 1
		if options.attractMode == 0
			if object.entityPos == 0
				temp2 = inputPress.buttonA
				temp2 |= inputPress.buttonB
				temp2 |= inputPress.buttonC
				temp2 &= inputDown.down
				if temp2 == 1
					object.state = PlayerObject_HandleAir
					player.doubleJumpState = 0
					object.animation = ANI_JUMPING
					object.yvel = 1
				end if
			end if
		end if
	end if
	//Fly Cancel
end function


function PlayerObject_StartTailsFlight
	if player.doubleJumpState == 1
		if inputPress.buttonY == 1
			CheckEqual(specialStage.emeralds, 127)
			temp0 = checkResult
			CheckGreater(player.rings, 49)
			temp0 &= checkResult
			CheckNotEqual(PlayerObject_SuperState, 1)
			temp0 &= checkResult
			CheckNotEqual(object[30].type, TypeName[Act Finish])
			temp0 &= checkResult
			CheckEqual(saved.superStates, 1)
			temp0 &= checkResult
			CheckEqual (player.invulnerable, 0)
			temp0 &= checkResult
			if temp0 == 1
				currentPlayer = object.entityPos
				CallFunction(PlayerObject_SuperTransform)
			end if
		end if
		if object[0].jumpPress == 1
			object.value1 = 0
			object.state = PlayerObject_HandleTailsFlight
			player.flightVelocity = 0x800
			if object.entityPos == 1
				object.yvel = 0
			end if
			if player.gravityValue == 0x3800
				PlaySfx(SfxName[Flying], 1)
				object.animation = ANI_FLYING
			else
				object.animation = ANI_SWIMMING
			end if
		end if
	end if
end function


function PlayerObject_StartKnuxGlide
	if player.doubleJumpState == 1
		if inputPress.buttonY == 1
			CheckEqual(specialStage.emeralds, 127)
			temp0 = checkResult
			CheckGreater(player.rings, 49)
			temp0 &= checkResult
			CheckNotEqual(PlayerObject_SuperState, 1)
			temp0 &= checkResult
			CheckNotEqual(object[30].type, TypeName[Act Finish])
			temp0 &= checkResult
			CheckEqual(saved.superStates, 1)
			temp0 &= checkResult
			CheckEqual (player.invulnerable, 0)
			temp0 &= checkResult
			
			if temp0 == 1
				currentPlayer = object.entityPos
				CallFunction(PlayerObject_SuperTransform)
			end if
		end if
		//CheckEqual(stage.player2Enabled, 1)
		//temp4 = checkResult
		//CheckEqual(object.up, 1)
		//temp4 &= checkResult
		//if temp4 == 0
			if object.jumpPress == 1
				object.speed = 0x40000
				object.yvel += 0x20000 //accuracy to 3AIR, for superglide
				if object.yvel < 0
					object.yvel = 0
				end if
				if object.direction == FLIP_NONE
					ObjectTileCollision(CSIDE_LWALL, 15, -2, object.collisionPlane)
					ObjectTileCollision(CSIDE_LWALL, 15, 11, object.collisionPlane)
					ObjectTileCollision(CSIDE_ROOF, 0, -15, object.collisionPlane)
					object.state = PlayerObject_KnuxGlideRight
					object.xvel = 0x40000
					object.value1 = 0
				else
					ObjectTileCollision(CSIDE_RWALL, -12, -2, object.collisionPlane)
					ObjectTileCollision(CSIDE_RWALL, -12, 11, object.collisionPlane)
					ObjectTileCollision(CSIDE_ROOF, 0, -15, object.collisionPlane)
					object.state = PlayerObject_KnuxGlideLeft
					object.xvel = -0x40000
					object.value1 = 256
				end if
				object.rotation = object.direction
				object.prevAnimation = ANI_GLIDING
				object.animation = ANI_GLIDING
				object.frame = 2
				object.animationTimer = 0
				object.animationSpeed = 0
			end if
		//end if
	end if
end function


function PlayerObject_HandleShadowAbilities
	if saved.Dropdash == 1
		if options.attractMode == 0
			CheckNotEqual(player.invincible, 0)
			temp0 = checkResult
			CheckEqual(PlayerObject_SuperState, 1)
			temp0 |= checkResult
			CheckLower(player.shield, 2)
			temp0 |= checkResult
			CheckEqual(player.shield, 5)
			temp0 |= checkResult
			CheckGreater(player.dropDashCharge,0)
			temp0 |= checkResult
			if temp0 == 1
				if player.doubleJumpState > 0
					if player.dropDashCharge > 0
						if inputDown.buttonB ==1
							player.dropDashCharge++
							if player.dropDashCharge == 21
								PlaySfx(SfxName[Drop Dash], 0)
								object.value2 = 0
							end if
							
						else
							object.value1 = 0
							player.dropDashCharge = 0
							if player.dropDashCharge < 21
								object.value2 = 0
							end if
						end if
					else
						if inputPress.buttonB == 1
							player.dropDashCharge = 2
						end if
					end if
				end if
			end if
		end if
	end if
	if player.doubleJumpState == 1
		if inputPress.buttonY == 1
			CheckEqual(specialStage.emeralds, 127)
			temp0 = checkResult
			CheckGreater(player.rings, 49)
			temp0 &= checkResult
			CheckNotEqual(PlayerObject_SuperState, 1)
			temp0 &= checkResult
			CheckNotEqual(object[30].type, TypeName[Act Finish])
			temp0 &= checkResult
			CheckEqual(saved.superStates, 1)
			temp0 &= checkResult
			CheckEqual (player.invulnerable, 0)
			temp0 &= checkResult
			
			if temp0 == 1
				currentPlayer = object.entityPos
				CallFunction(PlayerObject_SuperTransform)
			end if
		end if
		
		if inputPress.buttonA == 1
			PlaySfx(SfxName[Air Dash], 0)
			GetBit(temp0, object.direction, 0)
			if temp0 == 0
				object.xvel = 0x80000
			else
				object.xvel = -0x80000
			end if
			object.speed = object.xvel
			object.yvel = 0
			player.doubleJumpState = 2
			camera.lockTimer = 15
			screen.cameraStyle = 4

			if object.state == PlayerObject_RollingJump
				object.state = PlayerObject_HandleAir
			end if
		end if
		
		if PlayerObject_SuperState == 1
			if saved.gogoplus == 1
				if inputPress.buttonZ == 1	
					object.state = PlayerObject_ChaosBlast
					object.animation = 50
					object.value1 = 70		
					object.value2 = 0					
				end if
			end if	
		end if
	end if
end function


function PlayerObject_HandleGunShoot
	if object.value1 == 0	
		if object.gravity == GRAVITY_AIR
			object.animation = 53	
			object.speed = 0
			object.xvel = 0
			object.yvel = 0	
		else
			object.animation = 52
		end if	
		if object.GunBefore == 1	
			object.frame = 2
		else
			object.frame = 0
		end if			
	end if

	if object.gravity == GRAVITY_GROUND
		temp0 = 0x2500
		if object.direction == FLIP_X
			if object.speed < 0
				object.speed += temp0
			else
				object.speed = 0
			end if
		else
			if object.speed > 0
				object.speed -= temp0
			else
				object.speed = 0
			end if
		end if
	else
		if object.animation == 52
			CallFunction(PlayerObject_HandleAirMovement)
		end if
	end if

	object.value1++

	if object.value1 == 1
		PlaySfx(SfxName[Gun Shoot], 0)

		CreateTempObject(TypeName[Bullet], 0, object.xpos, object.ypos)
		if object.direction == FLIP_X
			object[tempObjectPos].xpos -= 0xA0000
			object[tempObjectPos].xvel = -0xC0000
			object[tempObjectPos].direction = FLIP_X
		else
			object[tempObjectPos].xpos += 0xA0000
			object[tempObjectPos].xvel = 0xC0000	
			object[tempObjectPos].direction = FLIP_NONE			
		end if

		if PlayerObject_SuperState != 1
			bullet.cap++
			if bullet.cap == 5
				player.gunReload = 60
				bullet.cap = 0
			end if
		end if
	end if
	
	if object.value1 == 12
		player.gunTimer = 10
	end if 
	
	if player.gunTimer > 0
		object.frame = 5
		object.animationSpeed = 0
		object.animationTimer = 0
	else
		if object.value1 > 18
			object.animationSpeed = 0
			object.animationTimer = 0
			CheckEqual(player.gunTimer, 0)
			temp1 = checkResult
			CheckEqual(player.gunReload, 0)
			temp1 &= checkResult
			CheckEqual(inputDown.buttonC, 1)
			temp1 &= checkResult	
			CheckLower(object.value1, 23)
			temp1 &= checkResult
			CheckLower(object.frame, 6)
			temp1 &= checkResult			
			if temp1 == 1
				object.frame = 5
				object.state = PlayerObject_HandleGunShoot
				object.value1 = 0
				player.gunTimer = 0
				object.GunBefore = 1
			else	
				if object.value1 >= 27
					if object.gravity == GRAVITY_AIR
						object.state = PlayerObject_HandleAir
						if object.animation == 52
							object.animation = ANI_WALKING
						end if
					else
						object.state = PlayerObject_HandleGround
					end if
					object.value1 = 0
					player.gunTimer = 0
					object.GunBefore = 0
				else
					if object.value1 >= 24
						if object.value1 < 27
							object.frame = 6
						end if
					else
						object.frame = 5					
					end if
				end if
			end if	
		end if	
	end if

end function

function PlayerObject_HandleAttack

end function


function PlayerObject_ChaosBlast
	if object.value1 == 70
		if saved.ShadowFX == 1
			PlaySfx(SfxName[Shadow Chaos], 0)
		end if
	end if

	if object.value1 == 20
		if saved.ShadowFX == 1
			StopSfx(SfxName[Charge Lazer])
			PlaySfx(SfxName[Shadow Blast], 0)
		end if
	end if

	if object.animation == 50
		if object.value2 == 2
			object.animationSpeed += 12
			object.value2 = 0
		end if
	end if	

	if object.frame == 3
		if BlastCharge == 0
			PlaySfx(SfxName[Charge Lazer], 0)
			BlastCharge++
		end if	
	end if

	if object.frame == 2
		BlastCharge = 0
	end if

	if PlayerObject_SuperState == 2
		object.state = PlayerObject_HandleAir
		object.animation = ANI_WALKING	
		StopSfx(SfxName[Charge Lazer])
		StopSfx(SfxName[Shadow Blast])
		StopSfx(SfxName[Lazer])
		StopSfx(SfxName[Big Blast])
	end if	
	
	if object.value1 == 19
		player.doubleJumpState = 2
		object.animation = 51
		ResetObjectEntity(13, TypeName[Insta Shield], 1, 0, 0)
		object[13].priority = PRIORITY_ACTIVE
		object[13].drawOrder = 5
		object[13].alpha = 224
		PlaySfx(SfxName[Lazer], 0)
		PlaySfx(SfxName[Big Blast], 0)
		StopSfx(SfxName[Charge Lazer])
	end if	

	player.collisionEnabled = 1
	object.value1--
	object.value2++
	if object.value1 == 0
		object.state = PlayerObject_HandleAir
		object.animation = ANI_WALKING
	end if	
end function


function PlayerObject_HandleGround	
	if object.animation != ANI_SKIDDING
		temp7 = 1
	else
		temp7 = 0
	end if
	CallFunction(PlayerObject_HandleMovement)
	if object.gravity == GRAVITY_AIR
		object.state = PlayerObject_HandleAir
		CallFunction(PlayerObject_HandleAirMovement)
	else
		CallFunction(PlayerObject_ResetOnFloor)
		if object.speed == 0
			if object.collisionMode == CMODE_FLOOR
				if object.value1 < 240
					object.animation = ANI_STOPPED
					object.value1++
				else
					object.animation = ANI_WAITING
					if stage.playerListPos == 2
						object.value1++
						if object.value1 == 836
							object.value1 = 0
							object.animation = ANI_STOPPED
						end if
					end if
					if stage.playerListPos == 5
						if options.gameMode != 3
							object.value1++
							if object.value1 == 10620
								object.value1 = 0
								PlaySfx(SfxName[OuttaHere], 0)
								object.state = PlayerObject_OuttaHere
								object.animation = 46
							end if
						end if
					end if
				end if
				switch object.propertyValue
				case 0
				case 1
				case 5
				case 6
					if object.floorSensorC == 0
						if object.floorSensorR == 0
							object.value1 = 0
							object.animation = ANI_FLAILING1
							object.direction = FLIP_NONE
						end if
						if object.floorSensorL == 0
							object.value1 = 0
							object.animation = ANI_FLAILING1
							object.direction = FLIP_X
						end if
					end if
					break
				case 2
					if object.floorSensorC == 0
						if object.floorSensorR == 0
							object.value1 = 0
							object.animation = ANI_FLAILING1
							if object.direction == FLIP_X
								object.prevAnimation = ANI_FLAILING1
								object.frame = 4
								object.animationTimer = 0
								object.animationSpeed = 0
							end if
							object.direction = FLIP_NONE
						end if
						if object.floorSensorL == 0
							object.value1 = 0
							object.animation = ANI_FLAILING1
							if object.direction == FLIP_NONE
								object.prevAnimation = ANI_FLAILING1
								object.frame = 4
								object.animationTimer = 0
								object.animationSpeed = 0
							end if
							object.direction = FLIP_X
						end if
					end if
					break
				end switch
			end if
		else
			object.value1 = 0
			CallFunction(PlayerObject_MoveAnimate)
		end if
		if player.skidding > 0
			if temp7 == 1
				PlaySfx(SfxName[Skidding], 0)
			end if
			object.animation = ANI_SKIDDING
			object.animationSpeed = 0
			player.skidding--
			if ringTimer == 0
				CreateTempObject(TypeName[Dust Puff], 0, object.xpos, object.ypos)
				object[tempObjectPos].iypos += object.collisionBottom
				object[tempObjectPos].drawOrder = player.sortedDrawOrder
			end if
			if object.speed > 0
				object.direction = FLIP_NONE
			else
				object.direction = FLIP_X
			end if
		end if
		if object.collisionMode == CMODE_FLOOR
			if object.pushing == 2
				object.animation = ANI_PUSHING
				object.animationSpeed = 0
			end if
		end if
		if stage.playerListPos == 6

			if object.controlMode >= 0
				temp0 = inputPress.buttonA
				temp0 |= inputPress.buttonB

				CheckEqual(player.gunTimer, 0)
				temp1 = checkResult
				CheckEqual(player.gunReload, 0)
				temp1 &= checkResult
				CheckEqual(inputPress.buttonC, 1)
				temp1 &= checkResult			
				if temp1 == 1
					object.value1 = 0
					if object.controlMode == 0
						object.state = PlayerObject_HandleGunShoot
					end if	
				end if

				if inputPress.buttonB == 1
					//object.animation = 54
					//object.state = PlayerObject_HandleAttack
					//player.timer = 0
				end if
			end if	
		else
			temp0 = object.jumpPress
		end if
		if temp0 == 1
			CheckEqual(object.propertyValue, 5)
			temp0 = checkResult
			CheckEqual(saved.AmyMoveset, 1)
			temp0 &= checkResult
			temp0 &= object.down
			if temp0 == 1
				CallFunction(PlayerObject_StartHop)
			else
				CallFunction(PlayerObject_StartJump)
			end if
		else
			if object.up == 1
				if object.speed == 0
					if object.animation != ANI_FLAILING1
						if object.animation != ANI_FLAILING2
							object.state = PlayerObject_LookingUp
							object.value1 = 0
						else
							object.up = 0
							object.down = 0
						end if
					else
						object.up = 0
						object.down = 0
					end if
				end if
			end if
			if object.down == 1
				if object.speed == 0
					if object.animation != ANI_FLAILING1
						if object.animation != ANI_FLAILING2
							object.state = PlayerObject_Crouching
							object.value1 = 0
						else
							object.up = 0
							object.down = 0
						end if
					else
						object.up = 0
						object.down = 0
					end if
				else
					if object.left == 0
						if object.right == 0
							CheckEqual(object.propertyValue, 5)
							temp0 = checkResult
							CheckEqual(saved.AmyMoveset, 1)
							temp0 &= checkResult
							if temp0 == 0
								if object.speed > 0
									if object.speed > 0x8800
										object.state = PlayerObject_HandleRoll
										object.animation = ANI_JUMPING
										if object.prevAnimation != ANI_JUMPING
											object.iypos -= player.jumpOffset
										end if
										object.value2 = 0x400
										PlaySfx(SfxName[Rolling], 0)
									end if
								else
									if object.speed < -0x8800
										object.state = PlayerObject_HandleRoll
										object.animation = ANI_JUMPING
										if object.prevAnimation != ANI_JUMPING
											object.iypos -= player.jumpOffset
										end if
										object.value2 = 0x400
										PlaySfx(SfxName[Rolling], 0)
									end if
								end if
							end if
						end if
					end if
				end if
			end if
		end if	
	end if
end function


function PlayerObject_HandleAir
		CallFunction(PlayerObject_HandleAirAcceleration)
		if object.gravity == GRAVITY_AIR
			CallFunction(PlayerObject_HandleAirMovement)
			if object.yvel > 0x20000
				if object.animation == ANI_FLAILING1
					object.animation = ANI_WALKING
				end if
				if object.animation == ANI_FLAILING2
					object.animation = ANI_WALKING
				end if
			end if
			if object.animation == ANI_BOUNCING
				if object.yvel >= 0
					if player.animationReserve == ANI_STOPPED
						player.animationReserve = ANI_WALKING
					end if
					if object.propertyValue == 5
						object.animation = ANI_FALL
					else
						object.animation = player.animationReserve
					end if
				end if
			else
				if object.animation == 11
					if object.yvel >= 0
						if player.animationReserve == ANI_STOPPED
							player.animationReserve = ANI_WALKING
						end if
						if object.propertyValue == 5
							object.animation = ANI_FALL
						else
							object.animation = player.animationReserve
						end if
					end if
				end if
			end if
			if stage.playerListPos == 6
				CheckEqual(player.gunTimer, 0)
				temp1 = checkResult
				CheckEqual(player.gunReload, 0)
				temp1 &= checkResult
				CheckEqual(inputPress.buttonC, 1)
				temp1 &= checkResult			
				if temp1 == 1
					if object.animation == 53
						if object.frame >= 2
							object.state = PlayerObject_HandleGunShoot
							object.value1 = 0
						end if
					else
						object.state = PlayerObject_HandleGunShoot
						object.value1 = 0
					end if	
				end if	
			end if				
			if object.animation == ANI_HAMMER_JUMP
				if object.yvel >= 100
					//object.rotation = 0
					//object.angle = 0
					object.animation = player.animationReserve
				end if
			end if
			if object.animation == ANI_HURT
				if object.yvel >= 0
					if player.animationReserve == ANI_STOPPED
						player.animationReserve = ANI_WALKING
					end if
					object.animation = player.animationReserve
				end if
			end if
			if object.animation == ANI_JUMPING
				//if player.doubleJumpState == 1
					if object.yvel >= player.jumpStrength
						CallFunction(player.jumpAbility)
					end if
				//end if
			end if
			if object.animation == ANI_SKIDDING
				if player.skidding > 0
					player.skidding--
				else
					object.animation = ANI_WALKING
					object.prevAnimation = ANI_WALKING
					object.frame = 0
					object.animationSpeed = 40
				end if
			end if
			if saved.AmyMoveset == 1
				if stage.playerListPos == 5
					CheckEqual(object.animation, 11)
					temp0 = checkResult
					CheckEqual(object.animation, ANI_FALL)
					temp0 |= checkResult
					CheckEqual(object.animation, 52)
					temp0 |= checkResult
					CheckEqual(object.animation, ANI_HAMMER_SPEEN)
					temp0 |= checkResult
					if temp0 == 1						
						CheckEqual(object.up, 1)
						temp1 = checkResult
						switch player.doubleJumpState
							case 1
								if inputPress.buttonY == 1
									CheckEqual(specialStage.emeralds, 127)
									temp0 = checkResult
									CheckGreater(player.rings, 49)
									temp0 &= checkResult
									CheckNotEqual(PlayerObject_SuperState, 1)
									temp0 &= checkResult
									CheckNotEqual(object[30].type, TypeName[Act Finish])
									temp0 &= checkResult
									CheckEqual(saved.superStates, 1)
									temp0 &= checkResult
									CheckEqual (player.invulnerable, 0)
									temp0 &= checkResult
									
									if temp0 == 1
										currentPlayer = object.entityPos
										CallFunction(PlayerObject_SuperTransform)
									end if
								end if
								if object.jumpPress == 1
									if temp1 == 1
										CallFunction(PlayerObject_StartSecondJump)
										player.doubleJumpState = 3
									else
										CallFunction(PlayerObject_StartHop)
										player.doubleJumpState = 4
									end if
								end if	
								break
							case 3
								if object.jumpPress == 1
									if temp1 == 0
										CallFunction(PlayerObject_StartHop)
										player.doubleJumpState = 2
									end if
								end if
								break
							case 4
								if object.jumpPress == 1
									if temp1 == 1
										CallFunction(PlayerObject_StartSecondJump)
										player.doubleJumpState = 2
									end if
								end if
								break
						end switch
					end if
				end if
			end if
		else
			if object.entityPos == 0
				if player.dropDashCharge < 21
					
					object.state = PlayerObject_HandleGround
					CallFunction(PlayerObject_ResetOnFloor)
					player.skidding = 0
					player.dropDashCharge = 0

				else	//release drop dash
					object.state = PlayerObject_HandleRoll
					StopSfx(SfxName[Drop Dash])
					CreateTempObject(TypeName[Dust Puff], object.entityPos, object.xpos, object.ypos)
					object[tempObjectPos].iypos = object.collisionBottom
					object[tempObjectPos].ypos += object.ypos
					object[tempObjectPos].frame = 11
					object[tempObjectPos].drawOrder = player.sortedDrawOrder
					object[tempObjectPos].direction = object.direction
					object.value1 = 0
					object.value2 = 0
					object.animation = ANI_JUMPING
					object.iypos -= player.jumpOffset
					if object.entityPos == 0
						camera.lockTimer = 15
						screen.cameraStyle = 4
					end if
					if PlayerObject_SuperState == 1
						temp0 = 0xC0000
						temp1 = 0xD0000
						screen.shakeX = 5
						screen.shakeY = 5
					else
						temp0 = 0x80000
						temp1 = 0xC0000
					end if

					if object.Direction==FLIP_X
						FlipSign(object.xvel)
						FlipSign(object.Speed)
					end if

					if object.xvel >= 0
						object.Speed >>= 2
						object.Speed += temp0
						if object.Speed > temp1
							object.Speed = temp1
						end if
					else
						object.Speed >>= 1
						object.Speed += temp0
					end if
					
					if object.Direction == FLIP_X
						FlipSign(object.xvel)
						FlipSign(object.Speed)
					end if
					
					CallFunction(PlayerObject_ResetOnFloor)
					StopSfx(SfxName[Charge])
					if PlayerObject_SuperState == 1
						PlaySfx(SfxName[Peelout Release],0)
					else
						PlaySfx(SfxName[Drop Dash Release],0)
					end if
					player.dropDashCharge = 0
				end if
			else
				object.state = PlayerObject_HandleGround
				CallFunction(PlayerObject_ResetOnFloor)
				player.skidding = 0
			end if
		end if
end function


function PlayerObject_AirCtrlLock
	CallFunction(PlayerObject_HandleAirAcceleration)
	if object.gravity == GRAVITY_AIR
		CallFunction(PlayerObject_HandleAirMovement)
	else
		object.state = PlayerObject_Unknown2
		CallFunction(PlayerObject_ResetOnFloor)
		player.skidding = 0
	end if
	object.animation = ANI_JUMPING
end function


function PlayerObject_HandleRoll
	CallFunction(PlayerObject_HandleRolling)
	if object.gravity == GRAVITY_AIR
		object.state = PlayerObject_HandleAir
		object.value1 = 0
		CallFunction(PlayerObject_HandleAirMovement)
	else
		CallFunction(PlayerObject_HandleRollAnimSpd)
		object.animationSpeed = player.CustomRollAnimSpeed
		CallFunction(PlayerObject_ResetOnFloor)
		if object.jumpPress == 1
			CallFunction(PlayerObject_StartJump)
		end if
	end if
end function


function PlayerObject_RollingJump
	if object.jumpPress == 1
		object.state = PlayerObject_HandleAir
	end if

	object.left = 0
	object.right = 0
	CallFunction(PlayerObject_HandleAirAcceleration)
	if object.gravity == GRAVITY_AIR
		if object.animation == ANI_JUMPING
			//if player.doubleJumpState == 1
				if object.yvel >= player.jumpStrength
					CallFunction(player.jumpAbility)
				end if
			//end if
		end if
		CallFunction(PlayerObject_HandleAirMovement)
	else
		if object.entityPos == 0
			if player.dropDashCharge < 21
				
				object.state = PlayerObject_HandleGround
				CallFunction(PlayerObject_ResetOnFloor)
				player.skidding = 0

			else	//release drop dash
				object.state = PlayerObject_HandleRoll
				CallFunction(PlayerObject_ResetOnFloor)
				StopSfx(SfxName[Drop Dash])
				CreateTempObject(TypeName[Dust Puff], object.entityPos, object.xpos, object.ypos)
				object[tempObjectPos].iypos = object.collisionBottom
				object[tempObjectPos].ypos += object.ypos
				object[tempObjectPos].frame = 11
				object[tempObjectPos].drawOrder = player.sortedDrawOrder
				object[tempObjectPos].direction = object.direction
				object.value1 = 0
				object.value2 = 0
				object.animation = ANI_JUMPING
				object.iypos -= player.jumpOffset
				if object.entityPos == 0
					camera.lockTimer = 15
					screen.cameraStyle = 4
				end if
				if PlayerObject_SuperState == 1
					temp0 = 0xC0000
					temp1 = 0xD0000
				else
					temp0 = 0x80000
					temp1 = 0xC0000
				end if

				if object.Direction==FLIP_X
					FlipSign(object.xvel)
				end if

				if object.xvel >= 0
					object.Speed>>=2
					object.Speed+=temp0
					if object.Speed > temp1
						object.Speed=temp1
					end if
				else
					object.Speed>>=1
					object.Speed+=temp0
				end if
				if object.Direction==FLIP_X
					FlipSign(object.xvel)
					FlipSign(object.Speed)
				end if
				StopSfx(SfxName[Charge])
				PlaySfx(SfxName[Release],0)
			end if
		else
			object.state = PlayerObject_HandleGround
			CallFunction(PlayerObject_ResetOnFloor)
			player.skidding = 0
		end if
	end if
end function


function PlayerObject_LookingUp
	CheckGreater(object.angle, 31)
	temp0 = checkResult
	CheckLower(object.angle, 225)
	temp0 &= checkResult
	CheckEqual(object.up, 0)
	temp0 |= checkResult
	if temp0 == 1
		object.state = PlayerObject_HandleGround
		object.value1 = 0
	else
		if object.value1 < 60
			object.value1++
		else
			temp0 = object.ypos
			temp0 >>= 16
			temp0 -= screen.cameraY
			temp0 -= 112
			if object.lookPosY > temp0
				object.lookPosY -= 2
			end if
		end if
		object.animation = ANI_LOOKINGUP
		if object.gravity == GRAVITY_AIR
			object.state = PlayerObject_HandleAir
			object.value1 = 0
		else
			if object.jumpPress == 1	
				switch stage.playerListPos
					case 0
      					//case 3
						if saved.Peelout == 1
							if options.attractMode == 0
								CallFunction(PlayerObject_StartSuperPeel)
							else
								CallFunction(PlayerObject_StartJump)							
							end if
						else
							CallFunction(PlayerObject_StartJump)
						end if
						break
					case 1
					case 2
						CallFunction(PlayerObject_StartJump)
						break	
					case 5	
						if saved.AmyMoveset == 0	
							CallFunction(PlayerObject_StartJump)
						else	
							CallFunction(PlayerObject_StartSuperPeel)
						end if
						break	
					case 6
						if saved.ShadowPeelout == 1
							if options.attractMode == 0
								CallFunction(PlayerObject_StartSuperPeel)
							else
								CallFunction(PlayerObject_StartJump)							
							end if
						else
							CallFunction(PlayerObject_StartJump)
						end if
						break							
				end switch
			end if
		end if
	end if
end function

function PlayerObject_HandleSuperPeel
	if object.gravity == GRAVITY_AIR
		object.state = PlayerObject_HandleAir
		object.speed = 0
	else
		if player.gravityValue == 0x1000
			if object.value2 < 0x60000
				object.value2 += 0x6000
			end if
		else
			if object.value2 < 0xC0000
				object.value2 += 0x6000
			end if
		end if
		if object.value2 < 0x5F5C2
			object.animation = ANI_WALKING
			object.animationSpeed = object.value2
			if object.animationSpeed < 0
				FlipSign(object.animationSpeed)
			end if
			object.animationSpeed *= 60
			object.animationSpeed /= 0x60000
			object.animationSpeed += 20
		else
			temp0 = object.value2
			if PlayerObject_SuperState == 1
				if temp0 > 0xAFFFF
					switch saved.SuperMaxDash
						case 0
							object.animation = ANI_RUNNING
							break
						case 1
							object.animation = ANI_PEELOUT
							break
						case 2
							object.animation = ANI_DASHMANIA
							break
					end switch
				else
					object.animation = ANI_RUNNING
				end if
			else				
				if temp0 > 0x9FFFF
					switch saved.SonicMaxDash
						case 0
							object.animation = ANI_RUNNING
							break
						case 1
							object.animation = ANI_PEELOUT
							break
						case 2
							object.animation = ANI_BDASH2
							break
						case 3
							object.animation = ANI_DASHMANIA
							break
					end switch
				else
					if saved.SonicMaxDash == 2
						if temp0 > 0x7FAE0
							object.animation = ANI_BDASH1
						else
							object.animation = ANI_RUNNING
						end if
					else
						object.animation = ANI_RUNNING
					end if
				end if
			end if

			object.animationSpeed = object.value2
			if object.animationSpeed < 0
				FlipSign(object.animationSpeed)
			end if
			object.animationSpeed *= 80
			object.animationSpeed /= 0x60000
		end if
		if object.up == 0
			object.State = PlayerObject_HandleGround
			if object.entityPos == 0
				object.value11 = 15
				screen.cameraStyle = 4
			end if
			if object.value2 < 0x5F5C2
				object.speed = 0
			else
				object.speed = object.value2
				if object.Direction == FLIP_X
					FlipSign(object.Speed)
				end if
				StopSfx(SfxName[Peelout Charge])
				PlaySfx(SfxName[Peelout Release], 0)
			end if
			CallFunction(PlayerObject_ResetOnFloor)
		end if
	end if
end function

function PlayerObject_HandleAmySuperPeel
	if object.gravity == GRAVITY_AIR
		object.state = PlayerObject_HandleAir
		object.speed = 0
	else
		if player.gravityValue == 0x1000
			if object.value2 < 0x60000
				object.value2 += 0x9000
			end if
		else
			if object.value2 < 0xC0000
				object.value2 += 0x9000
			end if
		end if
		if object.value2 < 0x5F5C2
			object.animation = ANI_WALKING
			object.animationSpeed = object.value2
			if object.animationSpeed < 0
				FlipSign(object.animationSpeed)
			end if
			object.animationSpeed *= 60
			object.animationSpeed /= 0x60000
			object.animationSpeed += 20
		else
			temp0 = object.value2
				if temp0 > 0x9FFFF
					switch saved.AmyMaxDash
						case 0
							object.animation = ANI_RUNNING
							break
						case 1
							object.animation = ANI_PEELOUT
							break
						case 2
							object.animation = 44
							break
					end switch
				else
					object.animation = ANI_RUNNING
				end if
			
			object.animationSpeed = object.value2
			if object.animationSpeed < 0
				FlipSign(object.animationSpeed)
			end if
			object.animationSpeed *= 80
			object.animationSpeed /= 0x60000
		end if
		if object.up == 0
			object.State = PlayerObject_HandleGround
			if object.entityPos == 0
				object.value11 = 15
				screen.cameraStyle = 4
			end if
			if object.value2 < 0x5F5C2
				object.speed = 0
			else
				object.speed = object.value2
				object.speed -= 0x1300
				if object.Direction == FLIP_X
					FlipSign(object.Speed)
				end if
				StopSfx(SfxName[Peelout Charge])
				PlaySfx(SfxName[Peelout Release], 0)
			end if
			CallFunction(PlayerObject_ResetOnFloor)
		end if
	end if
end function



function PlayerObject_StartSuperPeel
	if object.entityPos == 0
		if stage.playerListPos == 5
			object.state = PlayerObject_HandleAmySuperPeel
		else
			object.state = PlayerObject_HandleSuperPeel
		end if
		object.value2 = 0
		PlaySfx(SfxName[Peelout Charge], 0)
		object.animation = ANI_WALKING
	else
		CallFunction(PlayerObject_StartJump)
	end if
	
end function



function PlayerObject_Crouching
	CheckGreater(object.angle, 31)
	temp0 = checkResult
	CheckLower(object.angle, 225)
	temp0 &= checkResult
	CheckEqual(object.down, 0)
	temp0 |= checkResult
	if temp0 == 1
		object.state = PlayerObject_HandleGround
		object.value1 = 0
	else
		if object.value1 < 60
			object.value1++
		else
			temp0 = object.ypos
			temp0 >>= 16
			temp0 -= screen.cameraY
			temp0 += 96
			if object.lookPosY < temp0
				object.lookPosY += 2
			end if
		end if
		switch stage.playerListPos
		default
			object.animation = ANI_LOOKINGDOWN
			break
		case 6
			if saved.ShadowCrouch == 1
				object.animation = 58
			else
				object.animation = ANI_LOOKINGDOWN
			end if
			break
		end switch
		if object.gravity == GRAVITY_AIR
			object.state = PlayerObject_HandleAir
			object.value1 = 0
		else
			if object.jumpPress == 1
				CallFunction(player.spindashFunction)
			end if
		end if
	end if
end function


function PlayerObject_HandleSpindash
	if object.gravity == GRAVITY_AIR
		CallFunction(PlayerObject_HandleAirAcceleration)
		CallFunction(PlayerObject_HandleAirMovement)
	else
		object.speed = 0
		if object.jumpPress == 1
			if object.value2 < 0x90000
				object.value2 += 0x20000
			else
				object.value2 = 0x80000
			end if
			object.frame = 0
			PlaySfx(SfxName[Charge], 0)
		else
			temp0 = object.value2
			temp0 >>= 5
			object.value2 -= temp0
		end if
		if object.down == 0
			object.value1 = 0
			object.state = PlayerObject_HandleRoll
			object.animation = ANI_JUMPING
			object.iypos -= player.jumpOffset
			if object.entityPos == 0
				camera.lockTimer = 15
				screen.cameraStyle = 4
			end if
			temp0 = object.value2
			temp0 >>= 17
			temp0 <<= 16
			if PlayerObject_SuperState == 1
				temp0 += 0xB0000
			else
				temp0 += 0x80000
			end if
			if object.direction == FLIP_NONE
				object.speed = temp0
			else
				object.speed = temp0
				FlipSign(object.speed)
			end if
			StopSfx(SfxName[Charge])
			PlaySfx(SfxName[Release], 0)
			CallFunction(PlayerObject_ResetOnFloor)
		end if
	end if
end function


function PlayerObject_HandleSpindashCD
	if object.gravity == GRAVITY_AIR
		CallFunction(PlayerObject_HandleAirAcceleration)
		CallFunction(PlayerObject_HandleAirMovement)
	else
		object.speed = 0
		if player.gravityValue == 4096
			if object.value1 < 524288
				object.value1 += 24576
			end if
		else
			if object.value1 < 786432
				object.value1 += 24576
			end if
		end if
		if object.down==0
			if object.value1 < 195297
				object.speed = 0
				object.state = PlayerObject_HandleGround
			else
				object.state = PlayerObject_HandleRoll
				object.animation = ANI_JUMPING
				object.speed = object.value1
				if object.direction == FACING_LEFT
					FlipSign(object.speed)
				end if
				playsfx(7,0)
			end if
			CallFunction(PlayerObject_ResetOnFloor)
			object.value1 = 0
		end if
	end if
end function

function PlayerObject_StartFlyCarry
	if player.tailsGrabTimeout != 0
		player.tailsGrabTimeout--
	end if
	temp0 = object.xpos
	temp1 = object.ypos
	temp1 += 0x1F0000
	if object[0].animation == ANI_JUMPING
		temp1 += 0x50000
	end if
	temp0 -= object[0].xpos
	temp1 -= object[0].ypos
	if object[0].state != PlayerObject_FlyCarry
		CheckEqual(object[0].gravity, GRAVITY_GROUND)
		temp2 = checkResult
		CheckGreater(object.yvel, 0)
		temp2 &= checkResult
		if temp2 == 0
			CheckEqual(object[0].state, PlayerObject_HandleGround)
			temp2 = checkResult
			CheckEqual(object[0].state, PlayerObject_HandleRoll)
			temp2 |= checkResult
			CheckEqual(object[0].state, PlayerObject_HandleAir)
			temp2 |= checkResult
			CheckEqual(object[0].state, PlayerObject_RollingJump)
			temp2 |= checkResult
			CheckEqual(object[0].state, PlayerObject_LookingUp)
			temp2 |= checkResult
			CheckEqual(object[0].state, PlayerObject_Crouching)
			temp2 |= checkResult
			if temp2 != 0
				temp2 = temp0
				Abs(temp2)
				temp3 = temp1
				Abs(temp3)
				if temp2 <= 0x80000
					if temp3 <= 0x80000
						if player.tailsGrabTimeout == 0
							if object[0].down == 0
								object[0].animation = ANI_HANGING
								object[0].state = PlayerObject_FlyCarry
								object[0].xpos += temp0
								object[0].ypos += temp1
								PlaySfx(SfxName[Catch], 0)
							end if
						end if
					end if
				end if
			end if
		end if
	end if
	if object[0].state == PlayerObject_FlyCarry
		temp2 = object.xpos
		temp3 = object.ypos
		temp6 = object.xvel
		temp7 = object.yvel
		ProcessObjectMovement()
		PlayerObject_SidekickX = object.xpos
		PlayerObject_SidekickY = object.ypos
		temp4 = object.xpos
		temp4 &= -0x10000
		temp5 = object.ypos
		temp5 &= -0x10000
		temp5 += 0x1F0000
		object.xpos = temp2
		object.ypos = temp3
		object.xvel = temp6
		object.yvel = temp7
		stage.entityPos = 0
		temp0 = object.xpos
		temp0 &= -0x10000
		temp1 = object.ypos
		temp1 &= -0x10000
		object.xvel = temp4
		object.yvel = temp5
		object.xvel -= temp0
		object.yvel -= temp1
		ProcessObjectMovement()
		stage.entityPos = 1
		object[0].collisionPlane = object.collisionPlane
		object[0].speed = object.speed
		object[0].direction = object.direction
		PlayerObject_LeaderX = object[0].xpos
		PlayerObject_LeaderY = object[0].ypos
		temp2 = object[0].xpos
		temp2 &= -0x10000
		temp3 = object[0].ypos
		temp3 &= -0x10000
		CheckNotEqual(temp4, temp2)
		temp6 = checkResult
		CheckNotEqual(temp5, temp3)
		temp6 |= checkResult
		if temp6 == 1
			if object[0].gravity == GRAVITY_GROUND
				object[0].state = PlayerObject_HandleGround
			else
				object[0].state = PlayerObject_HandleAir
			end if
			player.tailsGrabTimeout = 30
		end if
	end if
end function


function PlayerObject_FlyCarry
	if object[1].state != PlayerObject_HandleTailsFlight
		object.state = PlayerObject_HandleAir
	end if
	temp0 = object[1].xpos
	temp0 &= -0x10000
	temp2 = object.xpos
	temp2 &= -0x10000
	if object.xpos == PlayerObject_LeaderX
		PlayerObject_SidekickX &= -0x10000
		temp1 = temp0
		temp1 -= PlayerObject_SidekickX
		temp2 += temp1
	end if
	if temp0 != temp2
		if object.gravity == GRAVITY_GROUND
			object.state = PlayerObject_HandleGround
		else
			object.state = PlayerObject_HandleAir
		end if
	end if
	if object.gravity == GRAVITY_GROUND
		if object.yvel >= 0
			object.state = PlayerObject_HandleGround
		end if
	end if
	if object.jumpPress != 0
		if object.down != 0
			if player.gravityValue == 0x3800
				object.yvel = -0x40000
			else
				object.yvel = -0x20000
			end if
			object.state = PlayerObject_HandleAir
			object.animation = ANI_JUMPING
		end if
	end if
	if object.state == PlayerObject_FlyCarry
		object.xvel = 0
		object.yvel = 0
		object.speed = 0
	else
		object[1].value36 = 30
	end if
end function


function PlayerObject_HandleTailsFlight
	CallFunction(PlayerObject_HandleAirAcceleration)
	if object.gravity == GRAVITY_AIR
		object.xvel = object.speed
		if object.yvel < -0x10000
			player.flightVelocity = 0x800
		else
			if object.yvel < 1
				if object.value2 < 60
					object.value2++
				else
					player.flightVelocity = 0x800
				end if
			end if
		end if
		object.yvel += player.flightVelocity
		if object.ypos < 0x100000
			if object.yvel < 0
				object.yvel = 0
			end if
		end if
		CallFunction(PlayerObject_StartFlyCarry)
		if object.value1 < 480
			if player.gravityValue == 0x3800
				if object[0].state == PlayerObject_FlyCarry
					if object.yvel < 0
						object.animation = ANI_FLY_LIFT_UP
						object.animationSpeed = 240
					else
						object.animation = ANI_FLY_LIFT_DOWN
						object.animationSpeed = 120
					end if
				else
					object.animation = ANI_FLYING
					if object.yvel < 0
						object.animationSpeed = 240
					else
						object.animationSpeed = 120
					end if
				end if
			else
				if object[0].state == PlayerObject_FlyCarry
					object.animation = ANI_SWIM_LIFT
				else
					object.animation = ANI_SWIMMING
					if object.yvel < 0
						object.animationSpeed = 60
					else
						object.animationSpeed = 30
					end if
				end if
			end if
			object.value1++
			if object.value1 == 480
				player.flightVelocity = 0x800
				if player.gravityValue == 0x3800
					if object[0].state == PlayerObject_FlyCarry
						object.animation = ANI_FLY_LIFT_TIRED
					else
						object.animation = ANI_FLYINGTIRED
					end if
					object.animationSpeed = 120
					StopSfx(SfxName[Flying])
					PlaySfx(SfxName[Tired], 1)
				else
					if object[0].state == PlayerObject_FlyCarry
						object.animation = ANI_SWIM_LIFT
					else
						object.animation = ANI_SWIMMINGTIRED
					end if
				end if
			else
				temp0 = object.collisionTop
				temp0 -= 2
				ObjectTileCollision(CSIDE_ROOF, 0, temp0, object.collisionPlane)
				if checkResult == 0
					CheckEqual(object.entityPos, 0)
					temp0 = checkResult
					CheckEqual(object[0].state, PlayerObject_FlyCarry)
					temp0 |= checkResult
					if temp0 == 1
						if object[0].jumpPress == 1
							CheckNotEqual(player.gravityValue, 0x3800)
							temp0 = checkResult
							CheckEqual(object[0].state, PlayerObject_FlyCarry)
							temp0 &= checkResult
							if temp0 == 0
								player.flightVelocity = -0x2000
								object.value2 = 0
							end if
						end if
						if object[0].up == 1
							CheckNotEqual(player.gravityValue, 0x3800)
							temp0 = checkResult
							CheckEqual(object[0].state, PlayerObject_FlyCarry)
							temp0 &= checkResult
							if temp0 == 0
								player.flightVelocity = -0x2000
								object.value2 = 0
							end if
						end if
					else
						player.targetLeaderPos.y = object[0].ypos
						if object[0].gravity == GRAVITY_GROUND
							temp0 = 75
						else
							temp0 = 10
						end if
						temp0 <<= 16
						FlipSign(temp0)
						temp0 += object[0].ypos
						if object.ypos > temp0
							if object[0].down == 0
									CheckNotEqual(player.gravityValue, 0x3800)
									temp0 = checkResult
									CheckEqual(object[0].state, PlayerObject_FlyCarry)
									temp0 &= checkResult
									if temp0 == 0
										player.flightVelocity = -0x2000
										object.value2 = 0
									end if
							end if
						else
							player.flightVelocity = 0x800
						end if				
					end if
				end if
			end if
		else
			if player.gravityValue == 0x3800
				if object[0].state == PlayerObject_FlyCarry
					object.animation = ANI_FLY_LIFT_TIRED
				else
					object.animation = ANI_FLYINGTIRED
				end if
			else
				if object[0].state == PlayerObject_FlyCarry
					object.animation = ANI_SWIM_LIFT
				else
					object.animation = ANI_SWIMMINGTIRED
				end if
			end if
		end if
	else
		object.animation = ANI_WALKING
		object.state = PlayerObject_HandleGround
		CallFunction(PlayerObject_ResetOnFloor)
	end if

	//Fly Cancel

	if saved.FlightCancel == 1
		if options.attractMode == 0
			if object.entityPos == 0
				temp2 = inputPress.buttonA
				temp2 |= inputPress.buttonB
				temp2 |= inputPress.buttonC
				temp2 &= inputDown.down
				if temp2 == 1
					object.state = PlayerObject_HandleAir
					player.doubleJumpState = 0
					object.animation = ANI_JUMPING
					object.yvel = 1
				end if
			end if
		end if
	end if
	//Fly Cancel
end function


function PlayerObject_KnuxGlideLeft
	if object.gravity == GRAVITY_AIR
		ObjectTileCollision(CSIDE_ROOF, 0, -15, object.collisionPlane)
		if object.jumpHold == 1
			if object.value1 == 256
				if object.speed < 0x180000
					object.speed += 0x400
				end if
			else
				if object.speed < 0x40000
					object.speed += 0x1000
				end if
			end if
			if object.yvel > 0x8000
				object.yvel -= 0x2000
			else
				object.yvel += 0x2000
			end if
			if object.value1 < 256
				object.value1 += 4
			end if
			if object.value1 < 170
				if object.value1 > 86
					object.frame = 0
				else
					if object.value1 > 44
						object.frame = 1
					else
						object.frame = 2
					end if
				end if
			else
				if object.value1 < 212
					object.frame = 1
				else
					object.frame = 2
				end if
			end if
			if object.frame == 2
				temp0 = oscillation
				temp0 >>= 2
				temp0 %= 2
				if temp0 == 1
					object.frame = 3
				end if				
			end if
			temp7 = object.xpos
			if object.value1 < 128
				object.direction = FLIP_NONE
				temp0 = 0
				temp1 = 0
			else
				object.direction = FLIP_X
				object.xpos = temp7
				object.xpos += object.xvel
				object.ypos = object.ypos
				ObjectTileCollision(CSIDE_RWALL, -12, -2, object.collisionPlane)
				temp0 = checkResult
				temp2 = object.xpos
				object.xpos = temp7
				object.xpos += object.xvel
				ObjectTileCollision(CSIDE_RWALL, -12, 11, object.collisionPlane)
				temp1 = checkResult
				temp3 = object.xpos
			end if
			Cos(object.xvel, object.value1)
			object.xvel *= object.speed
			object.xvel >>= 9
			if object.right == 1
				object.state = PlayerObject_KnuxGlideRight
			end if
			object.xpos = temp7
			checkResult = temp0
			checkResult &= temp1
			if checkResult == 1
				if temp2 == temp3
					object.state = PlayerObject_KnuxWallClimb
					if PlayerObject_SuperState == 1
						if saved.gogoplus > 0
							if object.speed > 0x48000
								ResetObjectEntity(13, TypeName[Insta Shield], 3, 0, 0)
								object[13].priority = PRIORITY_ACTIVE
								PlaySfx(SfxName[Thud],0)
							end if
						end if
					end if
					object.speed = 0
					object.xvel = 0
					object.yvel = 0
					object.value1 = 0
					PlaySfx(SfxName[Catch], 0)
				else
					object.value1 = 0
					object.xvel >>= 2
					object.speed = object.xvel
					object.animation = ANI_GLIDING_DROP
					object.state = PlayerObject_KnuxGlideDrop
				end if
			else
				if temp0 == 1
					object.value1 = 0
					object.xvel >>= 2
					object.speed = object.xvel
					object.animation = ANI_GLIDING_DROP
					object.state = PlayerObject_KnuxGlideDrop
				end if
			end if
		else
			object.value1 = 0
			object.xvel >>= 2
			object.speed = object.xvel
			object.animation = ANI_GLIDING_DROP
			if object[0].ixpos <= 10
				object.direction = FLIP_NONE
			endif
			object.state = PlayerObject_KnuxGlideDrop
		end if
	else
		if object.collisionMode == CMODE_FLOOR
			object.value1 = 0
			object.state = PlayerObject_KnuxGlideSlide
			object.animation = ANI_GLIDING_STOP
			object.speed = object.xvel
		else
			object.animation = ANI_WALKING
			object.speed >>= 1
			object.state = PlayerObject_HandleGround
			CallFunction(PlayerObject_ResetOnFloor)
			player.skidding = 0
		end if
	end if
	CallFunction(PlayerObject_TopGlide)
end function


function PlayerObject_KnuxGlideRight
	if object.gravity == GRAVITY_AIR
		ObjectTileCollision(CSIDE_ROOF, 0, -15, object.collisionPlane)
		if object.jumpHold == 1
			if object.value1 == 0
				if object.speed < 0x180000
					object.speed += 0x400
				end if
			else
				if object.speed < 0x40000
					object.speed += 0x1000
				end if
			end if
			if object.yvel > 0x8000
				object.yvel -= 0x2000
			else
				object.yvel += 0x2000
			end if
			if object.value1 > 0
				object.value1 -= 4
			end if
			if object.value1 < 170
				if object.value1 > 86
					object.frame = 0
				else
					if object.value1 > 44
						object.frame = 1
					else
						object.frame = 2
					end if
				end if
			else
				if object.value1 < 212
					object.frame = 1
				else
					object.frame = 2
				end if
			end if
			if object.frame == 2
				temp0 = oscillation
				temp0 >>= 2
				temp0 %= 2
				if temp0 == 1
					object.frame = 3
				end if				
			end if
			temp7 = object.xpos
			if object.value1 < 128
				object.direction = FLIP_NONE
				object.xpos = temp7
				object.xpos += object.xvel
				object.ypos = object.ypos
				ObjectTileCollision(CSIDE_LWALL, 12, -2, object.collisionPlane)
				temp0 = checkResult
				temp2 = object.xpos
				object.xpos = temp7
				object.xpos += object.xvel
				ObjectTileCollision(CSIDE_LWALL, 12, 11, object.collisionPlane)
				temp1 = checkResult
				temp3 = object.xpos
			else
				object.direction = FLIP_X
				temp0 = 0
				temp1 = 0
			end if
			Cos(object.xvel, object.value1)
			object.xvel *= object.speed
			object.xvel >>= 9
			if object.left == 1
				object.state = PlayerObject_KnuxGlideLeft
			end if
			object.xpos = temp7
			checkResult = temp0
			checkResult &= temp1
			if checkResult == 1
				temp2 >>= 1
				temp3 >>= 1
				if temp2 == temp3
					object.state = PlayerObject_KnuxWallClimb
					if PlayerObject_SuperState == 1
						if saved.gogoplus > 0
							if object.speed > 0x48000
								ResetObjectEntity(13, TypeName[Insta Shield], 3, 0, 0)
								object[13].priority = PRIORITY_ACTIVE
								PlaySfx(SfxName[Thud],0)
							end if
						end if
					end if
					object.speed = 0
					object.xvel = 0
					object.yvel = 0
					object.value1 = 0
					PlaySfx(SfxName[Catch], 0)
				else
					object.value1 = 0
					object.xvel >>= 2
					object.speed = object.xvel
					object.animation = ANI_GLIDING_DROP
					object.state = PlayerObject_KnuxGlideDrop
				end if
			else
				if temp0 == 1
					object.speed = 0
					object.value1 = 0
					object.xvel >>= 2
					object.speed = object.xvel
					object.animation = ANI_GLIDING_DROP
					object.state = PlayerObject_KnuxGlideDrop
				end if
			end if
		else
			object.value1 = 0
			object.xvel >>= 2
			object.speed = object.xvel
			object.animation = ANI_GLIDING_DROP
			object.state = PlayerObject_KnuxGlideDrop
		end if
	else
		if object.collisionMode == CMODE_FLOOR
			object.value1 = 0
			object.state = PlayerObject_KnuxGlideSlide
			object.animation = ANI_GLIDING_STOP
			object.speed = object.xvel
		else
			object.animation = ANI_WALKING
			object.speed >>= 1
			object.state = PlayerObject_HandleGround
			CallFunction(PlayerObject_ResetOnFloor)
			player.skidding = 0
		end if
	end if
	CallFunction(PlayerObject_TopGlide)
end function

function PlayerObject_TopGlide
	temp0 = stage.curYBoundary1
	temp0 += 16
	temp0 <<= 16
	if object.ypos < temp0
		object.xvel = 0
		object.speed = object.xvel
	end if
end function

function PlayerObject_KnuxGlideDrop
	if object.gravity == GRAVITY_AIR
		CallFunction(PlayerObject_HandleAirAcceleration)
		CallFunction(PlayerObject_HandleAirMovement)		
	else
		if object.value1 == 0
			PlaySfx(SfxName[Landing], 0)
		end if
		object.scrollTracking = 0
		object.speed = 0
		object.xvel = 0
		object.animation = ANI_LOOKINGDOWN
		object.prevAnimation = ANI_LOOKINGDOWN
		object.frame = 2
		if object.value1 < 11
			object.value1++
			if object.up == 1
					CallFunction(PlayerObject_ResetOnFloor)
					object.state = PlayerObject_LookingUp
					player.skidding = 0
			else
				if object.down == 1
						CallFunction(PlayerObject_ResetOnFloor)
						object.state = PlayerObject_Crouching
						player.skidding = 0
				else
					if object.jumpPress == 1
						player.skidding = 0
						CallFunction(PlayerObject_StartJump)
					end if
				end if
			end if
		else
			object.state = PlayerObject_HandleGround
			CallFunction(PlayerObject_ResetOnFloor)
			player.skidding = 0
		end if
	end if
end function


function PlayerObject_KnuxGlideSlide
	if object.gravity == GRAVITY_GROUND
		if object.speed == 0
			if object.jumpPress == 1
				if object.down == 1
					CallFunction(PlayerObject_ResetOnFloor)
					object.state = player.spindashFunction
					player.skidding = 0
				else
					player.skidding = 0
					CallFunction(PlayerObject_StartJump)
				end if
			end if
			object.scrollTracking = 0
			object.frame = 1
			if object.value1 < 16
				object.value1++
			else
				object.state = PlayerObject_HandleGround
				CallFunction(PlayerObject_ResetOnFloor)
				player.skidding = 0
			end if
		else
			if ringTimer == 0
				CreateTempObject(TypeName[Dust Puff], 0, object.xpos, object.ypos)
				object[tempObjectPos].iypos += object.collisionBottom
				object[tempObjectPos].drawOrder = player.sortedDrawOrder
				if object.value1 == 0
					PlaySfx(SfxName[Sliding], 0)
					object.value1 = 1
				else
					object.value1 = 0
				end if
			end if
			object.frame = 0
			if object.speed > 0
				object.speed -= 0x2000
				if object.speed < 0
					object.speed = 0
					object.value1 = 0
				end if
			else
				object.speed += 0x2000
				if object.speed > 0
					object.speed = 0
					object.value1 = 0
				end if
			end if
			if object.jumpHold == 0
				object.speed = 0
				object.value1 = 0
			end if
		end if
		object.xvel = object.speed
	else
		object.value1 = 0
		object.animation = ANI_GLIDING_DROP
		object.state = PlayerObject_KnuxGlideDrop
	end if
end function


function PlayerObject_KnuxWallClimb
	if object.gravity == GRAVITY_AIR
		object.animation = ANI_CLIMBING
		if object.up == 1
			if PlayerObject_SuperState == 1
				object.yvel = -0x20000
			else
				object.yvel = -0x10000
			end if
			temp0 = object.collisionTop
			temp0 *= -0x10000
			if object.ypos < temp0
				object.ypos = temp0
			end if
			object.value1++
			if object.value1 == 4
				object.value1 = 0
				object.frame++
				object.frame %= 6
			end if
		else
			if object.down == 1
				if PlayerObject_SuperState == 1
					object.yvel = 0x20000
				else
					object.yvel = 0x10000
				end if
				object.value1++
				if object.value1 == 4
					object.value1 = 0
					if object.frame < 1
						object.frame += 6
					end if
					object.frame--
				end if
			else
				object.yvel = 0
			end if
		end if
		if object.jumpPress == 1
			object.animation = ANI_JUMPING
			object.state = PlayerObject_HandleAir
			object.value1 = 0
			PlaySfx(SfxName[Jump], 0)
			if object.direction == FLIP_X
				object.xvel = 0x40000
				object.speed = 0x40000
				object.direction = FLIP_NONE
			else
				object.xvel = -0x40000
				object.speed = -0x40000
				object.direction = FLIP_X
			end if
			object.yvel = -0x40000
			if player.gravityValue != 0x3800
				object.xvel >>= 1
				object.speed >>= 1
				object.yvel >>= 1
			end if
		else
			if object.direction == FLIP_NONE
				temp2 = object.xpos
				ObjectTileGrip(CSIDE_LWALL, 10, -10, object.collisionPlane)
				temp0 = checkResult
				temp3 = object.xpos
				object.xpos = temp2
				ObjectTileGrip(CSIDE_LWALL, 10, 11, object.collisionPlane)
				temp1 = checkResult
				if object.xpos > temp3
					object.xpos = temp3
				end if
			else
				temp2 = object.xpos
				ObjectTileGrip(CSIDE_RWALL, -10, -10, object.collisionPlane)
				temp0 = checkResult
				temp3 = object.xpos
				object.xpos = temp2
				ObjectTileGrip(CSIDE_RWALL, -10, 11, object.collisionPlane)
				temp1 = checkResult
				if object.xpos < temp3
					object.xpos = temp3
				end if
			end if
			if temp0 == 0
				object.xpos = temp2
				object.animation = ANI_LEDGEPULLUP
				object.yvel = 0
				object.value1 = 0
				object.state = PlayerObject_KnuxLedgePullUp
				object.tileCollisions = 0
				if object.direction == FLIP_NONE
					object.xpos += 0x10000
				end if
			else
				if temp1 == 0
					object.animation = ANI_GLIDING_DROP
					object.prevAnimation = ANI_GLIDING_DROP
					object.frame = 2
					object.value1 = 0
					object.state = PlayerObject_KnuxGlideDrop
				end if
			end if
		end if
	else
		object.animation = ANI_WALKING
		object.state = PlayerObject_HandleGround
		CallFunction(PlayerObject_ResetOnFloor)
	end if
end function


function PlayerObject_KnuxLedgePullUp
	switch object.frame
	case 0
		if object.value1 < 5
			ObjectTileGrip(CSIDE_FLOOR, 12, -9, object.collisionPlane)
			object.value1++
		else
			object.value1 = 0
			object.frame++
			if object.direction == FLIP_NONE
				object.xpos += 0x90000
			else
				object.xpos -= 0x90000
			end if
			object.ypos -= 0xA0000
		end if
		break
	case 1
		if object.value1 < 5
			object.value1++
		else
			object.value1 = 0
			object.frame++
			if object.direction == FLIP_NONE
				object.xpos += 0x50000
			else
				object.xpos -= 0x50000
			end if
			object.ypos -= 0x20000
		end if
		break
	case 2
		if object.value1 < 5
			object.value1++
		else
			object.value1 = 0
			object.animation = ANI_STOPPED
			object.state = PlayerObject_HandleAir
			object.ypos -= 0xA0000
			object.tileCollisions = 1
		end if
		break
	end switch
end function


function PlayerObject_Hurt
	if player.isPlayer2 == 0
		arrayPos0 = object.entityPos
		arrayPos0 += playerCount
		switch player.shield
		//if player.shield != 0
			case 1
			case 2
			case 3
			case 4
				temp0 = 1
				ResetObjectEntity(arrayPos0, TypeName[Blank Object], 0, 0, 0)
				player.shield = 0
				CheckEqual(saved.spikeBehavior, 0)
				temp1 = checkResult
				if options.attractMode == 1
					temp1 = 1
				end if
				CheckNotEqual(player.invulnerable, 0)
				temp1 &= checkResult
				if temp1 == 1
					if stage.playerListPos == 6
						if saved.ShadowFX == 1
							PlaySfx(SfxName[Shadow Spike], 0)				
						else
							PlaySfx(SfxName[Spike], 0)
						end if	
					else
						PlaySfx(SfxName[Spike], 0)
					end if
				else
					if stage.playerListPos == 6
						if saved.ShadowFX == 1
							PlaySfx(SfxName[Shadow Hurt], 0)				
						else
							PlaySfx(SfxName[Hurt], 0)
						end if	
					else
						PlaySfx(SfxName[Hurt], 0)
					end if					
				end if

				break
		//else
			case 5
			case 0
				ResetObjectEntity(arrayPos0, TypeName[Blank Object], 0, 0, 0)
				player.shield = 0
				if object[0].value0 == 0
					if player.invulnerable != 0
						if stage.playerListPos == 6
							if saved.ShadowFX == 1
								PlaySfx(SfxName[Shadow Spike], 0)				
							else
								PlaySfx(SfxName[Spike], 0)
							end if	
						else
							PlaySfx(SfxName[Spike], 0)
						end if
					else
						if stage.playerListPos == 6
							if saved.ShadowFX == 1
								PlaySfx(SfxName[Shadow Hurt], 0)				
							else
								PlaySfx(SfxName[Hurt], 0)
							end if	
						else
							PlaySfx(SfxName[Hurt], 0)
						end if					
					end if
					temp0 = 3
				else
					if stage.playerListPos == 6
						if saved.ShadowFX == 1
							PlaySfx(SfxName[Shadow Lose Rings], 0)				
						else
							PlaySfx(SfxName[Lose Rings], 0)
						end if	
					else
						PlaySfx(SfxName[Lose Rings], 0)
					end if
					temp0 = 2
				end if
				break
		//end if
		end switch
	else
		temp0 = 1
		if player.invulnerable != 0
			if stage.playerListPos == 6
				if saved.ShadowFX == 1
					PlaySfx(SfxName[Shadow Spike], 0)				
				else
					PlaySfx(SfxName[Spike], 0)
				end if	
			else
				PlaySfx(SfxName[Spike], 0)
			end if
		else
			if stage.playerListPos == 6
				if saved.ShadowFX == 1
					PlaySfx(SfxName[Shadow Hurt], 0)				
				else
					PlaySfx(SfxName[Hurt], 0)
				end if	
			else
				PlaySfx(SfxName[Hurt], 0)
			end if					
		end if
	end if
	object.visible = 1
	switch temp0
	case 1
		object.state = PlayerObject_Knockback
		object.animation = ANI_HURT
		object.yvel = -0x40000
		object.gravity = GRAVITY_AIR
		object.scrollTracking = 1
		object.tileCollisions = 1
		player.invulnerable = 120
		if player.gravityValue == 0x1000
			object.speed >>= 1
			object.yvel >>= 1
		end if
		break
	case 2
		object.state = PlayerObject_Knockback
		object.animation = ANI_HURT
		object.yvel = -0x40000
		object.gravity = GRAVITY_AIR
		object.scrollTracking = 1
		object.tileCollisions = 1
		player.invulnerable = 120
		if player.gravityValue == 0x1000
			object.speed >>= 1
			object.yvel >>= 1
		end if
		temp0 = object[0].value0
		if temp0 > 16
			temp1 = temp0
			temp1 -= 16
			temp0 = 16
		else
			temp1 = 0
		end if
		if temp1 > 16
			temp1 = 16
		end if
		temp3 = temp1
		temp3 >>= 1
		temp3 <<= 5
		temp2 = 384
		temp2 -= temp3
		temp3 >>= 4
		if temp3 == temp1
			temp2 += 16
		else
			temp2 -= 16
		end if
		temp3 = 0
		while temp3 < temp1
			CreateTempObject(TypeName[Lose Ring], object.collisionPlane, object.xpos, object.ypos)
			Cos(object[tempObjectPos].xvel, temp2)
			Sin(object[tempObjectPos].yvel, temp2)
			object[tempObjectPos].xvel <<= 8
			object[tempObjectPos].yvel <<= 8
			object[tempObjectPos].animationSpeed = 256
			object[tempObjectPos].inkEffect = INK_ALPHA
			object[tempObjectPos].alpha = 256
			temp3++
			temp2 += 32
		loop
		temp3 = temp0
		temp3 >>= 1
		temp3 <<= 5
		temp2 = 384
		temp2 -= temp3
		temp3 >>= 4
		if temp3 == temp0
			temp2 += 16
		else
			temp2 -= 16
		end if
		temp3 = 0
		while temp3 < temp0
			CreateTempObject(TypeName[Lose Ring], object.collisionPlane, object.xpos, object.ypos)
			Cos(object[tempObjectPos].xvel, temp2)
			Sin(object[tempObjectPos].yvel, temp2)
			object[tempObjectPos].xvel <<= 9
			object[tempObjectPos].yvel <<= 9
			object[tempObjectPos].animationSpeed = 256
			object[tempObjectPos].inkEffect = INK_ALPHA
			object[tempObjectPos].alpha = 256
			temp3++
			temp2 += 32
		loop
		object[0].value0 = 0
		ringExtraLife = 100
		if stage.debugMode == 0
			saveRAM[997] = 0
		end if
		break
	case 3
		player.sortedDrawOrder = 6
		object.speed = 0
		object.yvel = -0x70000
		object.xvel = 0
		stage.pauseEnabled = 0
		object.state = PlayerObject_Death
		object.animation = ANI_DYING
		object.tileCollisions = 0
		object.interaction = 0
		if object.entityPos == 0
			object.priority = PRIORITY_ACTIVE_PAUSED
			if object[1].type == TypeName[Player 2 Object]
				object[1].priority = PRIORITY_ACTIVE_PAUSED
			end if
			screen.cameraEnabled = 0
			stage.state = 3
		end if
		if object[+playerCount].type == invincibilityType
			object[+playerCount].propertyValue = 3
		end if
		object[+playerCount].type = TypeName[Blank Object]
		break
	end switch
end function


function PlayerObject_Knockback
	if object.gravity == GRAVITY_AIR		
		player.hitboxTop = HITBOX_AUTO
		player.hitboxBottom = HITBOX_AUTO
		player.hitboxRight = HITBOX_AUTO
		player.hitboxLeft = HITBOX_AUTO
		object.scrollTracking = 1
		if player.gravityValue == 0x3800
			object.yvel += 0x3000
		else
			object.yvel += 0xF00
		end if
		object.xvel = object.speed
	else
		object.state = PlayerObject_HandleGround
		object.speed = 0
		object.xvel = 0
		CallFunction(PlayerObject_ResetOnFloor)
	end if	
end function


function PlayerObject_Death
	if object.entityPos == 0
		stage.pauseEnabled = 0
		if PlayerObject_SuperState == 1
			PlayerObject_SuperState = 2
		end if
	end if
	if object.controlMode != -1
		object.yvel = -0x70000
		object.controlMode = -1
	end if
	if player.invulnerable != 0
		player.invulnerable = 0
		object.visible = 1
	end if
	object.yvel += 0x3800
	if object.animation != ANI_BORED
		if object.animation != 46
			object.animation = ANI_DYING
		end if
	end if
	if object.yvel > 0x100000
		if player.isPlayer2 == 0
			if saved.lives == 0
				CheckEqual(stage.playerListPos, 5)
				temp0 = checkResult
				CheckEqual(object.animation, 46)
				temp0 &= checkResult				
				if temp0 == 1
					player.lives = 0
				else
					player.lives--
				endif
			end if
			stage.timeEnabled = 0
			object.type = TypeName[Death Event]
			object.drawOrder = 6
			object.value1 = screen.xcenter
			object.value1 -= 264
			object.value2 = screen.xcenter
			object.value2 += 200
			if options.gameMode == 2
				player.drownCounter = 0
				object.state = 3
			else
				if player.lives == 0
					player.drownCounter = -0xB40
					object.state = 0
					PlayMusic(5)
					stage.pauseEnabled = 0
				else
					if TimeOverFlag == 1
						player.drownCounter = -0xB40
						object.state = 1
						PlayMusic(5)
						stage.pauseEnabled = 0					
					else
						player.drownCounter = 0
						object.state = 2
					end if					
				end if
			end if
		end if
	end if
end function


function PlayerObject_Drown
	if object.entityPos == 0
		stage.pauseEnabled = 0
		if PlayerObject_SuperState == 1
			PlayerObject_SuperState = 2
		end if
	end if
	object.controlMode = -1
	object.yvel += player.gravityValue
	object.animation = ANI_DROWNING
	if object.yvel > 0x80000
		if player.isPlayer2 == 0
			if saved.lives == 0
				player.lives--
			end if
			stage.timeEnabled = 0
			object.type = TypeName[Death Event]
			object.drawOrder = 6
			object.value1 = screen.xcenter
			object.value1 -= 264
			object.value2 = screen.xcenter
			object.value2 += 200
			if options.gameMode == 2
				player.drownCounter = 0
				object.state = 3
			else
				if player.lives == 0
					player.drownCounter = -0xB40
					object.state = 0
					PlayMusic(5)
					stage.pauseEnabled = 0
				else
					player.drownCounter = 0
					object.state = 2
				end if
			end if
		end if
	end if
end function


function PlayerObject_CheckTile
	if object.left == 1
		object.direction = FLIP_X
		object.speed = -0x20000
		object.animationSpeed = 30
	else
		if object.right == 1
			object.direction = FLIP_NONE
			object.speed = 0x20000
			object.animationSpeed = 30
		else
			object.speed = 0
			object.animationSpeed = 0
		end if
	end if
	temp1 = object.xpos
	temp1 >>= 16
	temp2 = object.ypos
	temp2 >>= 16
	temp2 += object.collisionTop
	Get16x16TileInfo(temp0, temp1, temp2, TILEINFO_ANGLEB)
	if temp0 != 3
		object.state = PlayerObject_HandleAir
		object.speed = 0
		object.animationSpeed = 0
		object.yvel = 0
	end if
	if object.jumpPress == 1
		object.state = PlayerObject_HandleAir
		object.yvel = 0
		object.speed = 0
		object.animationSpeed = 0
		object.ypos += 0x40000
	end if
	object.xvel = object.speed
end function


function PlayerObject_Unknown1
	object.angle = 0
	CallFunction(PlayerObject_HandleMovement)
	object.animation = 34
	if object.speed < 0x60000
		if object.speed > -0x60000
			object.animation = ANI_WALKING
			object.state = PlayerObject_HandleAir
			object.rotation = 0
			if object.speed < 0
				object.direction = FLIP_X
			end if
		end if
	end if
	if object.down == 1
		if object.speed > 0x199A
			object.state = PlayerObject_RollUnknown
			object.animation = ANI_JUMPING
		end if
		if object.speed < -0x199A
			object.state = PlayerObject_RollUnknown
			object.animation = ANI_JUMPING
		end if
	end if
	if player.skidding > 0
		if player.skidding == 16
			PlaySfx(SfxName[Destroy], 0)
		end if
		object.animation = ANI_SKIDDING
		player.skidding--
	end if
	if object.jumpPress == 1
		CallFunction(PlayerObject_StartJump)
	else
		CallFunction(PlayerObject_ResetOnFloor)
	end if
end function


function PlayerObject_RollUnknown
	object.angle = 0
	CallFunction(PlayerObject_HandleRolling)
	if object.speed < 0x60000
		if object.speed > -0x60000
			object.state = PlayerObject_HandleAir
		end if
	end if
	if object.jumpPress == 1
		CallFunction(PlayerObject_StartJump)
	else
		CallFunction(PlayerObject_ResetOnFloor)
	end if
end function


function PlayerObject_Unknown2
	if object.gravity == GRAVITY_AIR
		object.state = PlayerObject_AirCtrlLock
		object.value1 = 0
		CallFunction(PlayerObject_HandleAirMovement)
	else
		if object.speed > 0
			if object.collisionMode == CMODE_FLOOR
				if object.speed < 0x10000
					object.speed = 0x40000
				end if
			end if
		else
			if object.collisionMode == CMODE_FLOOR
				if object.speed > -0x10000
					object.speed = -0x40000
				end if
			end if
		end if
		if object.right == 1
			if object.speed < 0
				object.speed += player.rollingDecelerationP
			end if
		end if
		if object.left == 1
			if object.speed > 0
				object.speed -= player.rollingDecelerationP
			end if
		end if
		if object.speed > 0
			object.speed -= player.rollingDecelerationA
			Sin256(temp0, object.angle)
			if temp0 > 0
				Sin256(temp0, object.angle)
				temp0 *= 0x5000
			else
				Sin256(temp0, object.angle)
				temp0 *= 0x1E00
			end if
			temp0 >>= 8
			object.speed += temp0
		else
			object.speed += player.rollingDecelerationA
			Sin256(temp0, object.angle)
			if temp0 < 0
				Sin256(temp0, object.angle)
				temp0 *= 0x5000
			else
				Sin256(temp0, object.angle)
				temp0 *= 0x1E00
			end if
			temp0 >>= 8
			object.speed += temp0
		end if
		CallFunction(PlayerObject_HandleRollAnimSpd)
		object.animationSpeed = player.CustomRollAnimSpeed
		CallFunction(PlayerObject_ResetOnFloor)
	end if
end function


function PlayerObject_Clinging
	object.gravity = GRAVITY_AIR
	if object.animation != ANI_CLINGING
		object.xvel = 0x80000
		object.speed = 0x80000
	else
		object.xvel = 0
		object.speed = 0
	end if
	if object.up == 1
		object.ypos -= 0x10000
	else
		if object.down == 1
			object.ypos += 0x10000
		end if
	end if
	object.yvel = 0
end function


function PlayerObject_WaterSlide
	if object.gravity == GRAVITY_AIR
		object.state = PlayerObject_HandleAir
		object.angle = 0
		object.collisionMode = CMODE_FLOOR
		object.value1 = 0
		CallFunction(PlayerObject_HandleAirMovement)
		object.animation = ANI_WATERSLIDE
	else
		if object.direction == FLIP_NONE
			object.speed = 0xA0000
		else
			object.speed = -0xA0000
		end if
		CallFunction(PlayerObject_HandleRollAnimSpd)
		object.animation = ANI_WATERSLIDE
		CallFunction(PlayerObject_ResetOnFloor)
		if object.jumpPress == 1
			CallFunction(PlayerObject_StartJump)
		end if
	end if
end function


function PlayerObject_HandleRunSpd2
	if object.speed > 0x10000
		object.value1 = 0
		CallFunction(PlayerObject_MoveAnimate)
	end if
end function

function PlayerObject_OuttaHere
	if object.value1 < 140
		object.value1++
	else
		object.value1 = 0
		player.sortedDrawOrder = 5
		if object.direction == FLIP_NONE
			object.speed = 0x10000
			object.xvel = 0x10000
		else
			object.speed = -0x10000
			object.xvel = -0x10000
		end if
		object.yvel = -0x58000
		object.state = PlayerObject_Death
		object.tileCollisions = 0
		object.interaction = 0
		if object.entityPos == 0
			object.priority = PRIORITY_ACTIVE_PAUSED
			if object[1].type == TypeName[Player 2 Object]
				object[1].priority = PRIORITY_ACTIVE_PAUSED
			end if
			screen.cameraEnabled = 0
			stage.state = 3
		end if
		if object[+playerCount].type == invincibilityType
			object[+playerCount].propertyValue = 3
		end if
		if object[+playerCount].type != goggleType
			object[+playerCount].type = TypeName[Blank Object]
		end if
	endif
end function

function PlayerObject_MoveAnimate
	temp0 = object.speed
	abs(temp0)
	
	if temp0 < 0x5F5C2
		object.animation = ANI_WALKING
		CallFunction(PlayerObject_HandleWalkAnimSpd)
	else
		switch object.propertyValue
			case 0 //Sonic
				if PlayerObject_SuperState == 1
					if temp0 > 0xAFFFF
						switch saved.SuperMaxDash
							case 0
								object.animation = ANI_RUNNING
								break
							case 1
								object.animation = ANI_PEELOUT
								break
							case 2
								object.animation = ANI_DASHMANIA
								break
						end switch
					else
						object.animation = ANI_RUNNING
					end if
				else				
					if temp0 > 0x9FFFF
						switch saved.SonicMaxDash
							case 0
								object.animation = ANI_RUNNING
								break
							case 1
								object.animation = ANI_PEELOUT
								break
							case 2
								object.animation = ANI_BDASH2
								break
							case 3
								object.animation = ANI_DASHMANIA
								break
						end switch
					else
						if saved.SonicMaxDash == 2
							if temp0 > 0x7FAE0
								object.animation = ANI_BDASH1
							else
								object.animation = ANI_RUNNING
							end if
						else
							object.animation = ANI_RUNNING
						end if
					end if
				end if
				break
			case 1 //Tails
				if temp0 > 0x9DDDD
					switch saved.TailsMaxDash
						case 0
							object.animation = ANI_RUNNING
							break
						case 1
							object.animation = ANI_PEELOUT
							break
						case 2
							object.animation = ANI_DASHMANIA
							break
					end switch
				else
					object.animation = ANI_RUNNING
				end if
				break
			case 2 //Knuckles
				if temp0 > 0x9FFFF
					switch saved.KnuxMaxDash
						case 0
							object.animation = ANI_RUNNING
							break
						case 1
							object.animation = ANI_PEELOUT
							break
						case 2
							object.animation = ANI_DASHMANIA
							break
					end switch
				else
					object.animation = ANI_RUNNING
				end if
				break	
			case 5 //Amy
				if temp0 > 0x9FFFF
					switch saved.AmyMaxDash
						case 0
							object.animation = ANI_RUNNING
							break
						case 1
							object.animation = ANI_PEELOUT
							break
						case 2
							object.animation = 44
							break
					end switch
				else
					object.animation = ANI_RUNNING
				end if
				break		
			case 6 //Amy
				object.animation = ANI_RUNNING
				break					
		end switch
		CallFunction(PlayerObject_HandleRunAnimSpd)
	end if
end function


event ObjectMain
	if SuperTimeAttack == 2
		SuperTimeAttack = 1
		currentPlayer = 0
		CallFunction(PlayerObject_SuperTransform)
	end if
	if stage.debugMode == 1
		CallFunction(PlayerObject_ProcessPlayer)
		CheckEqual(options.attractMode, 0)
		temp0 = checkResult
		CheckEqual(inputPress.buttonB, 1)
		temp0 &= checkResult
		if temp0 == 1
		
			CheckEqual(object.animation, ANI_DROWNING)
			temp1 = checkResult
			CheckEqual(object.animation, ANI_DYING)
			temp1 |= checkResult
			if temp1 == 1
				stage.timeEnabled = 1
				stage.pauseEnabled = 1
			end if			
			
			object.type = TypeName[Debug Mode]
			object.yvel = 0
			object.state = PlayerObject_Blank
			object.frame = 0
			object.rotation = 0
			object.interaction = 0
			object.drawOrder = 4
			object.priority = PRIORITY_ACTIVE
			player.invulnerable = 0
			object.visible = 1
			object.value2 = 0
			player.drownCounter = 0
			player.drownLevel = 0
			object.frame = debugMode.currentSelection
			screen.cameraEnabled = 1
			screen.cameraStyle = 0
			player.hitboxTop = HITBOX_AUTO
			player.hitboxBottom = HITBOX_AUTO
			player.hitboxLeft = HITBOX_AUTO
			player.hitboxRight = HITBOX_AUTO
			if stage.state == 3
				stage.state = STAGE_RUNNING
			end if
			stage.pauseEnabled = 1
			if object[1].type == TypeName[Player 2 Object]
				object[1].priority = PRIORITY_ACTIVE
			end if
			if object[+playerCount].propertyValue == 3
				object[+playerCount].type = invincibilityType
				object[+playerCount].propertyValue = 0
			end if
		else
			if object.gravity == GRAVITY_GROUND
				player.doubleJumpState = 0
			end if
			CallFunction(object.state)
			ProcessAnimation()
			if object.entityPos == screen.cameraTarget
				if object.animation == ANI_JUMPING
					screen.adjustCameraY = player.jumpOffset
				else
					if screen.adjustCameraY == player.jumpOffset
						screen.adjustCameraY = 0
						object.iypos += player.jumpOffset
					end if
				end if
			end if
			if player.collisionEnabled == 0
				temp0 = player.prevGravity
				player.prevGravity = object.gravity
				ProcessObjectMovement()
				player.prevGravity ^= 1
				CheckEqual(object.gravity, GRAVITY_GROUND)
				player.prevGravity |= checkResult
				player.prevGravity ^= 1
				if temp0 == 1
					if player.prevGravity == 0
						player.enemyChainCounter = 0
						achieveRingCount = 0
						if object.animation == ANI_JUMPING
							if object.down == 0
								if object.state != PlayerObject_BubbleBounce
									if object.state != PlayerObject_HandleRoll
										if object.state != PlayerObject_Unknown2
											//if player.dropDashCharge < 21
												object.animation = ANI_WALKING
												if object.entityPos == screen.cameraTarget
													screen.adjustCameraY = 0
												end if
												object.iypos += player.jumpOffset
											//end if
										end if
									end if
								end if
							end if
						end if
					end if
				end if
			else
				player.collisionEnabled = 0
			end if
		end if
	else
		CallFunction(PlayerObject_ProcessPlayer)
		if object.gravity == GRAVITY_GROUND
			player.doubleJumpState = 0
		end if
		CallFunction(object.state)
		ProcessAnimation()
		if object.entityPos == screen.cameraTarget
			if object.animation == ANI_JUMPING
				screen.adjustCameraY = player.jumpOffset
			else
				if screen.adjustCameraY == player.jumpOffset
					screen.adjustCameraY = 0
					object.iypos += player.jumpOffset
				end if
			end if
		end if
		if player.collisionEnabled == 0
			temp0 = player.prevGravity
			player.prevGravity = object.gravity
			ProcessObjectMovement()
			player.prevGravity ^= 1
			CheckEqual(object.gravity, GRAVITY_GROUND)
			player.prevGravity |= checkResult
			player.prevGravity ^= 1
			if temp0 == 1
				if player.prevGravity == 0
					player.enemyChainCounter = 0
					achieveRingCount = 0
					if object.animation == ANI_JUMPING
						if object.down == 0
							if object.state != PlayerObject_BubbleBounce
								if object.state != PlayerObject_HandleRoll
									if object.state != PlayerObject_Unknown2
										if player.dropDashCharge < 21
											object.animation = ANI_WALKING
											if object.entityPos == screen.cameraTarget
												screen.adjustCameraY = 0
											end if
											object.iypos += player.jumpOffset
										end if
									end if
								end if
							end if
						end if
					end if
				end if
			end if
		else
			player.collisionEnabled = 0
		end if
	end if
	CallFunction(PlayerObject_ProcessSuperForms)

	if inputPress.buttonY == 1
		if options.gameMode == 2
			if stage.timeEnabled == 1
				stage.timeEnabled = 0
				ResetObjectEntity(11, TypeName[Title Card], 0, 0, 0)
				object[11].state = 10
				object[11].priority = PRIORITY_ACTIVE
				object[11].drawOrder = 6
				player.invincible = 80
				screen.cameraEnabled = 0			
			end if
		else
			if PlayerObject_SuperState == 1
				if object.animation != ANI_SUPER_TRANSFORM
					if saved.Supercancel == 1
						CallFunction(PlayerObject_EndSuper)
					end if
				end if
			end if
		end if
	end if

	if player.gunReload > 0
		player.gunReload--
	else
		player.gunReload = 0
	end if
	
	if player.gunTimer > 0
		player.gunTimer--
	else
		player.gunTimer = 0
	end if	
end event

event ObjectDraw
		if player.dropDashCharge >= 21
			CheckEqual(object.animation,ANI_JUMPING)
			temp0 = checkResult
			CheckEqual(object.animation,ANI_WALKING)
			temp0 |= checkResult
			CheckEqual(object.animation,ANI_STOPPED)
			temp0 |= checkResult
			if temp0 == 0
				player.dropDashCharge = 0
			end if
		else
			temp0 = 0
		end if

		if temp0 == 1
			object.value2++
			object.value2 %= 8
		
			DrawSpriteFX(object.value2 , FX_FLIP, object.xpos, object.ypos)
		else
			if object.animation != object.prevAnimation
				object.prevAnimation = object.animation
				object.frame = 0
				object.animationTimer = 0
				object.animationSpeed = 0
			end if
			
			if saved.rotate == 0
				CallFunction(PlayerObject_Force45)
			else
				CallFunction(PlayerObject_ManiaRotate)
				//DrawObjectAnimation()
			end if
		end if
end event

function PlayerObject_Force45
	if object.gravity == GRAVITY_AIR
		CheckEqual(stage.playerListPos, 5)
		temp0 = checkResult
		CheckEqual(object.animation, ANI_HAMMER_JUMP)
		temp0 &= checkResult
		if temp0 == 1
			if object.direction == 0
				object.rotation += amy.spin.speed
			else
				object.rotation -= amy.spin.speed
			end if
		else		
			if object.rotation < 256
				if object.rotation > 3
					object.rotation -= 4
				else
					object.rotation = 0
				end if
			else
				if object.rotation < 509
					object.rotation += 4
				else
					object.rotation = 0
				end if
			end if
		end if
	end if
	temp0 = object.rotation
	if object.rotation >= 0x100
		temp1 = 532
		temp1 -= object.rotation
		temp1 >>= 6
		object.rotation = 8
		object.rotation -= temp1
	else
		object.rotation += 20
		object.rotation >>= 6
	end if
	if object.rotation == 8
		object.rotation = 0
	end if
	object.rotation <<= 6
	DrawObjectAnimation()
	object.rotation = temp0
end function

function PlayerObject_ManiaRotate
	temp0 = object.rotation
	if object.gravity == GRAVITY_GROUND
		if object.angle < 0x04
			player.groundrotation = 0
		else
			if object.angle > 0xFC
				player.groundrotation = 0
			else
				temp1 = 0
				if object.angle > 0x10
					if object.angle < 0xE8
						temp1 = object.angle
						temp1 <<= 1
					end if
				end if
				
				temp2 = temp1
				temp2 -= player.groundrotation
				temp3 = 1
				temp4 = object.speed
				abs(temp4)
				if temp4 <= 0x60000
					temp3++
				end if
				temp4 = temp2
				abs(temp4)
				temp5 = temp2
				temp5 -= 0x200
				abs(temp5)
				if temp4 >= temp5
					temp4 = temp2
					temp4 += 0x200
					abs(temp4)
					if temp5 < temp4
						temp4 = temp2
						temp4 -= 0x200
						temp4 >>= temp3
						player.groundrotation += temp4
					else
						temp4 = temp2
						temp4 += 0x200
						temp4 >>= temp3
						player.groundrotation += temp4
					end if
				else
					temp5 = temp2
					temp5 += 0x200
					if temp4 < temp5
						temp4 = temp2
						temp4 >>= temp3
						player.groundrotation += temp4
					else
						temp4 = temp2
						temp4 += 0x200
						temp4 >>= temp3
						player.groundrotation += temp4
					end if
				end if
			end if
		end if
	else
		CheckEqual(stage.playerListPos, 5)
		temp0 = checkResult
		CheckEqual(object.animation, ANI_HAMMER_JUMP)
		temp0 &= checkResult
		if temp0 == 1
			if object.direction == 0
				player.groundrotation += amy.spin.speed
			else
				player.groundrotation -= amy.spin.speed
			end if
			temp0 = player.groundrotation
		else		
			if player.groundrotation < 256
				if player.groundrotation > 3
					player.groundrotation -= 4
				else
					player.groundrotation = 0
				end if
			else
				if player.groundrotation < 509
					player.groundrotation += 4
				else
					player.groundrotation = 0
				end if
			end if
		end if
	end if
	player.groundrotation &= 0x1FF
	object.rotation = player.groundrotation
	DrawObjectAnimation()
	object.rotation = temp0
end function


event ObjectStartup
	playerCount = 0
	foreach (TypeName[Player Object], arrayPos0, ALL_ENTITIES)
		screen.cameraEnabled = 1
		screen.cameraStyle = 0
		screen.cameraTarget = 0
		currentPlayer = 0
		switch stage.playerListPos
			case 3
				stage.playerListPos = 0
				stage.player2Enabled = 1
				break
			case 4
				stage.playerListPos = 2
				stage.player2Enabled = 1
				break
			case 100
				stage.playerListPos = 0
				SuperTimeAttack = 1
				break
		end switch
		
		ResetObjectEntity(0, TypeName[Player Object], 0, object[arrayPos0].xpos, object[arrayPos0].ypos)
		screen.cameraX = object[0].ixpos
		screen.cameraY = object[0].iypos
		object[0].groupID = GROUP_PLAYERS
		object[0].state = PlayerObject_HandleAir
		object[0].priority = PRIORITY_ACTIVE
		object[0].drawOrder = -1
		object[0].value18 = 4
		object[0].value31 = 0x2000
		
		if SuperTimeAttack == 1 //Super Sonic Time Attack
			object[0].value0 = 20
		end if
		
		switch saved.spindash
   		case 0
			if options.attractMode == 0
				object[0].value33 = PlayerObject_StartJump
			else
				object[0].value33 = PlayerObject_StartSpindash
			end if
    			break
  		case 1
			object[0].value33 = PlayerObject_StartSpindash
			break
		case 2
			object[0].value33 = PlayerObject_StartSpindashCD
			break
		end switch

		if stage.playerListPos == 5
			if saved.amymoveset == 1
				object[0].value33 = PlayerObject_StartHop
			end if
		end if
		object[0].value38 = HITBOX_AUTO
		object[0].value39 = HITBOX_AUTO
		object[0].value40 = HITBOX_AUTO
		object[0].value41 = HITBOX_AUTO
		PlayerObject_SuperState = 0
		PlayerObject_value1 = 0
		PlayerObject_value2 = 0
		PlayerObject_value3 = 0


		switch stage.playerListPos
		case 0
			LoadAnimation("SuperSonic.ani")
			LoadAnimation("Sonic.ani")
			CallFunction(PlayerObject_HandleSuperPalSonic)
			object[0].propertyValue = 0
			object[0].value30 = -5
			object[0].value32 = PlayerObject_HandleShieldAbilities
			break
		case 1
			object[0].type = TypeName[Tails Object]
			object[0].propertyValue = 1
			CallFunction(PlayerObject_HandleSuperPalTails)
			LoadAnimation("Tails.ani")
			object[0].value30 = -1
			object[0].value32 = PlayerObject_StartTailsFlight
			stage.player2Enabled = 0
			break
		case 2
			LoadAnimation("Knuckles.ani")
			CallFunction(PlayerObject_HandleSuperPalKnux)
			object[0].propertyValue = 2
			object[0].value30 = -5
			object[0].value32 = PlayerObject_StartKnuxGlide
			break
		case 5
			LoadAnimation("Amy.ani")
			CallFunction(PlayerObject_HandleSuperPalAmy)
			object[0].propertyValue = 5
			object[0].value30 = -5
			object[0].value32 = PlayerObject_StartHammerSpin
			stage.player2Enabled = 0
			break
		case 6
			LoadAnimation("SuperShadow.ani")
			LoadAnimation("Shadow.ani")
			CallFunction(PlayerObject_HandleSuperPalShadow)
			object[0].propertyValue = 6
			object[0].value30 = -5
			object[0].value32 = PlayerObject_HandleShadowAbilities
			break			
		end switch

		if saved.Speen == 1
			ANI_BOUNCING = ANI_SPEEN
		else
			ANI_BOUNCING = 11
		end if 

		if stage.player2Enabled == 1
			playerCount = 2
		else
			playerCount = 1
		end if
		currentPlayer = 0
		CallFunction(PlayerObject_SwapPhysics)
		ResetObjectEntity(arrayPos0, TypeName[Blank Object], 0, 0, 0)
	next
	goggleType = TypeName[Goggles]
		
	if stage.playerListPos == 0
		LoadSpriteSheet("Players/Sonic4.gif")
		//DropDash Sprites
		SpriteFrame(-16, -16, 32, 32, 1, 180) //0
		SpriteFrame(-16, -16, 32, 32, 34, 180) //1
		SpriteFrame(-16, -16, 32, 32, 1, 213) //2
		SpriteFrame(-16, -16, 32, 32, 67, 180) //3
		SpriteFrame(-16, -16, 32, 32, 1, 180) //4
		SpriteFrame(-16, -16, 32, 32, 100, 180) //5
		SpriteFrame(-16, -16, 32, 32, 1, 213) //6
		SpriteFrame(-16, -16, 32, 32, 133, 180) //7
	else
		LoadSpriteSheet("Players/Shadow1.gif")
		SpriteFrame(-14, -15, 28, 30, 93, 152) //0
		SpriteFrame(-15, -14, 30, 28, 122, 152) //1
		SpriteFrame(-14, -15, 28, 30, 153, 151) //2
		SpriteFrame(-15, -14, 30, 28, 182, 151) //3
		SpriteFrame(-14, -15, 28, 30, 213, 151) //4
		SpriteFrame(-15, -14, 30, 28, 1, 182) //5
		SpriteFrame(-14, -15, 28, 30, 32, 182) //6
		SpriteFrame(-15, -14, 30, 28, 61, 183) //7
	end if
	
	//Shadow 3
	SpriteFrame(-7, -36, 14, 7, 33, 134) //8
	SpriteFrame(-7, -36, 14, 7, 33, 142) //9
	SpriteFrame(-7, -36, 14, 7, 33, 150) //10
	SpriteFrame(-7, -36, 14, 7, 33, 158) //11
end event
end event

event RSDKDraw
	DrawSprite(0)
end event

event RSDKLoad
	LoadSpriteSheet("Players/Sonic1.gif")
	SpriteFrame(-16, -19, 28, 39, 1, 1)
end event
